{"id":13743,"date":"2024-12-24T14:57:53","date_gmt":"2024-12-24T13:57:53","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=13743"},"modified":"2025-04-04T12:44:22","modified_gmt":"2025-04-04T10:44:22","slug":"evolution-of-a-sql-domain-for-semantic-versioning","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/","title":{"rendered":"Evolution of a SQL Domain for Semantic Versioning"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"1_introduction\">1. Introduction<\/h2>\n\n\n\n<p>In my current project, I use a SQL domain to implement the formatting and precedence rules for <a href=\"https:\/\/semver.org\/\">Semantic Versioning<\/a>. I started with a simple implementation covering only the most basic rules. Getting the sorting right is key in my project. It allows me to identify the latest compatible version of an artefact. After adding some tests I started to evolve the functionality to a point where I can say that the implementation covers everything needed for my use case.<\/p>\n\n\n\n<p>Domains make data models easier to understand and reduce the logic regarding data consistency and visualisation. In this blog post, I demonstrate this by evolving a domain for Semantic Versioning. This should give you an impression of whether keeping domains and table columns in sync is more complicated than traditional approaches.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2_what_are_domains\">2. What Are Domains?<\/h2>\n\n\n\n<p>A data use case domain (aka SQL domain, aka domain) is a new feature in the Oracle Database 23ai based on the SQL standard. Domains abstract column properties so that they can be used across multiple tables. They come in different flavours:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/23\/sqlrf\/create-domain.html#GUID-17D3A9C6-D993-4E94-BF6B-CACA56581F41__GUID-598818DB-33F2-467F-9D29-DDA3D50B1843\">Single-column domain<\/a> (constraints for a single column, enums, display and order expressions)<\/li>\n\n\n\n<li><a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/23\/sqlrf\/create-domain.html#GUID-17D3A9C6-D993-4E94-BF6B-CACA56581F41__GUID-79818F7A-115B-487D-B214-1A9ADB4EC9C6\">Multi-column domain<\/a> (constraints across multiple columns, display and order expressions)<\/li>\n\n\n\n<li><a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/23\/sqlrf\/create-domain.html#GUID-17D3A9C6-D993-4E94-BF6B-CACA56581F41__GUID-91BA6AC3-2762-495A-AC2B-D8822D100A95\">Flexible domain<\/a> (abstract domain, delegating functionality to concrete domains via discriminator columns)<\/li>\n<\/ul>\n\n\n\n<p>It&#8217;s important to notice, that a table column can have only one domain. It is therefore not possible to combine single-column domains with multi-column or flexible domains.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3_starting_model\">3. Starting Model<\/h2>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"3_1_domains\">3.1 Domains<\/h5>\n\n\n\n<p>First, let&#8217;s create three domains.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">1) create domains app_identifier, app_file_name and app_semantic_version<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create domain if not exists app_identifier\n   as raw(16) strict\n   display lower(substr(rawtohex(app_identifier), 1, 8)\n           || '-' || substr(rawtohex(app_identifier), 9, 4)\n           || '-' || substr(rawtohex(app_identifier), 13, 4)\n           || '-' || substr(rawtohex(app_identifier), 17, 4)\n           || '-' || substr(rawtohex(app_identifier), 21, 12));\n\ncreate domain if not exists app_file_name\n   as varchar2(128 char) strict;\n\ncreate domain if not exists app_semantic_version\n   as varchar2(20 byte) strict\n   -- na\u00efve, incomplete implementation of semantic versioning\n   constraint app_semantic_version_has_major_minor_patch_ck\n      check (regexp_like(app_semantic_version, '\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}'))\n   order to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 1)), 'FM000000')\n      || '.' || to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 2)), 'FM000000')\n      || '.' || to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 3)), 'FM000000');\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_identifier<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">raw<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">16<\/span><span style=\"color: #D4D4D4\">) strict<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   display <\/span><span style=\"color: #DCDCAA\">lower<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rawtohex<\/span><span style=\"color: #D4D4D4\">(app_identifier), <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           || <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rawtohex<\/span><span style=\"color: #D4D4D4\">(app_identifier), <\/span><span style=\"color: #B5CEA8\">9<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           || <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rawtohex<\/span><span style=\"color: #D4D4D4\">(app_identifier), <\/span><span style=\"color: #B5CEA8\">13<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           || <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rawtohex<\/span><span style=\"color: #D4D4D4\">(app_identifier), <\/span><span style=\"color: #B5CEA8\">17<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           || <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rawtohex<\/span><span style=\"color: #D4D4D4\">(app_identifier), <\/span><span style=\"color: #B5CEA8\">21<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">12<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_file_name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">128<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">char<\/span><span style=\"color: #D4D4D4\">) strict;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_semantic_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">20<\/span><span style=\"color: #D4D4D4\"> byte) strict<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- na\u00efve, incomplete implementation of semantic versioning<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">constraint<\/span><span style=\"color: #D4D4D4\"> app_semantic_version_has_major_minor_patch_ck<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">check<\/span><span style=\"color: #D4D4D4\"> (regexp_like(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}&#39;<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   order <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Domain APP_IDENTIFIER created.\n\n\nDomain APP_FILE_NAME created.\n\n\nDomain APP_SEMANTIC_VERSION created.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Domain APP_IDENTIFIER created.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Domain APP_FILE_NAME created.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Domain APP_SEMANTIC_VERSION created.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The domain <code>app_identifier<\/code> defines the data type for a GUID-based identifier. It also defines the display format.<\/p>\n\n\n\n<p>The domain <code>app_file_name<\/code> defines only the data type used for file names.<\/p>\n\n\n\n<p>The domain <code>app_semantic_version<\/code> is an incomplete implementation of <a href=\"https:\/\/semver.org\/spec\/v2.0.0.html\">Semantic Versioning 2.0.0<\/a> (we will fix that later). It defines the data type, a check constraint <code>app_semantic_version_has_major_minor_patch_ck<\/code> and an order expression.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"3_2_table\">3.2 Table<\/h5>\n\n\n\n<p>Let&#8217;s create a table using all these domains and insert a few rows.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">2) create table with some data<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create table if not exists app_files (\n    file_id      app_identifier       default sys_guid() not null,\n    file_name    app_file_name                           not null,\n    file_version app_semantic_version                    not null,\n    constraint app_files_pk primary key (file_id),\n    constraint app_files_uk1 unique (file_name, file_version)\n);\n\ndesc app_files\n\ninsert into app_files\n   (file_name, file_version)\nvalues\n   ('file1.txt', '1.9.0'),\n   ('file1.txt', '1.10.0'),\n   ('file1.txt', '1.11.0'),\n   ('file1.txt', '2.0.0'),\n   ('file2.txt', '0.0.7'),\n   ('file2.txt', '0.0.42');\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_files (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    file_id      app_identifier       <\/span><span style=\"color: #569CD6\">default<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">sys_guid<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    file_name    app_file_name                           <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    file_version app_semantic_version                    <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">constraint<\/span><span style=\"color: #D4D4D4\"> app_files_pk <\/span><span style=\"color: #569CD6\">primary key<\/span><span style=\"color: #D4D4D4\"> (file_id),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">constraint<\/span><span style=\"color: #D4D4D4\"> app_files_uk1 <\/span><span style=\"color: #569CD6\">unique<\/span><span style=\"color: #D4D4D4\"> (file_name, file_version)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">insert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">into<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (file_name, file_version)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">values<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file1.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.9.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file1.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.10.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file1.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.11.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file1.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;2.0.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file2.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;0.0.7&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file2.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;0.0.42&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Table APP_FILES created.\n\nName         Null?    Type                                     \n------------ -------- ---------------------------------------- \nFILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER       \nFILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME  \nFILE_VERSION NOT NULL VARCHAR2(20) DOMAIN APP_SEMANTIC_VERSION \n\n6 rows inserted.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Table APP_FILES created.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Name         Null?    Type                                     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------ -------- ---------------------------------------- <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">FILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER       <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">FILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME  <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">FILE_VERSION NOT NULL VARCHAR2(20) DOMAIN APP_SEMANTIC_VERSION <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">6 rows inserted.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Look at the result of the <code>desc app_files<\/code> command. Each column has a concrete data type inherited from the domain, as well as the domain associated with it.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"3_3_demo\">3.3 Demo<\/h5>\n\n\n\n<p>Now, let&#8217;s query the data to demonstrate the domain functionality.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">3) demo domain functionality<\/span><span role=\"button\" tabindex=\"0\" data-code=\"column file_name format a9\nselect domain_display(file_id) as file_id,\n       file_name,\n       file_version,\n       domain_order(file_version) as file_version_order\n  from app_files\n order by file_name, file_version_order desc;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_name format a9<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> domain_display(file_id) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_version,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       domain_order(file_version) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_version_order<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">order by<\/span><span style=\"color: #D4D4D4\"> file_name, file_version_order <\/span><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"FILE_ID                              FILE_NAME FILE_VERSION         FILE_VERSION_ORDER     \n------------------------------------ --------- -------------------- -----------------------\n29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0                000002.000000.000000   \n29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0               000001.000011.000000   \n29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0               000001.000010.000000   \n29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0                000001.000009.000000   \n29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42               000000.000000.000042   \n29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7                000000.000000.000007   \n\n6 rows selected. \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">FILE_ID                              FILE_NAME FILE_VERSION         FILE_VERSION_ORDER     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------------------------------ --------- -------------------- -----------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0                000002.000000.000000   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0               000001.000011.000000   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0               000001.000010.000000   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0                000001.000009.000000   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42               000000.000000.000042   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7                000000.000000.000007   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">6 rows selected. <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>You see the file version is sorted according to the <a href=\"https:\/\/semver.org\/#spec-item-11\">specification in 11.2<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&#8220;Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: Major, minor, and patch versions are always compared numerically.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4_test\">4. Test<\/h2>\n\n\n\n<p>The semantic versioning specification covers a lot of ground that our simple implementation can barely cover. So let&#8217;s test it, to find out what is missing. We use <a href=\"https:\/\/www.utplsql.org\/documentation.html\">utPLSQL<\/a>, of course.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"4_1_define_test\">4.1 Define Test<\/h5>\n\n\n\n<p>Let&#8217;s create a utPLSQL test PL\/SQL package.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">4) utPLSQL test package<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create or replace package test_app_domains is\n   --%suite\n\n   --%test\n   procedure test_app_semantic_version;\nend test_app_domains;\n\/\n\ncreate or replace package body test_app_domains is\n   procedure test_app_semantic_version is\n      c_actual   sys_refcursor;\n      c_expected sys_refcursor;\n   begin\n      open c_actual for\n         select input_col,\n                to_char(domain_check(app_semantic_version, input_col)) as test_check,\n                case when domain_check(app_semantic_version, input_col) then domain_order(cast(input_col as app_semantic_version)) end as test_order\n           from (values\n                   -- https:\/\/semver.org\/#spec-item-2\n                   ('1.9.0'),\n                   ('1.10.0'),\n                   ('1.11.0'),\n                   -- https:\/\/semver.org\/#spec-item-9\n                   ('1.0.0-alpha'),\n                   ('1.0.0-alpha.1'),\n                   ('1.0.0-0.3.7'),\n                   ('1.0.0-x.7.z.92'),\n                   ('1.0.0-x-y-z.--'),\n                   -- https:\/\/semver.org\/#spec-item-10\n                   ('1.0.0-alpha+001'),\n                   ('1.0.0+20130313144700'),\n                   ('1.0.0-beta+exp.sha.5114f85'),\n                   ('1.0.0+21AF26D3----117B344092BD'),\n                   -- https:\/\/semver.org\/#spec-item-11\n                   ('1.0.0'),\n                   ('2.0.0'),\n                   ('2.1.0'),\n                   ('2.1.1'),\n                   ('1.0.0-alpha'),\n                   ('1.0.0-alpha.1'),\n                   ('1.0.0-alpha.beta'),\n                   ('1.0.0-beta'),\n                   ('1.0.0-beta.2'),\n                   ('1.0.0-beta.11'),\n                   ('1.0.0-rc.1'),\n                   -- invalid\n                   ('01.0.0'),\n                   ('1.00.0'),\n                   ('1.0.00'),\n                   ('1.0.x')\n                ) as t(input_col);\n      open c_expected for\n         select *\n           from (values\n                   -- https:\/\/semver.org\/#spec-item-2\n                   ('1.9.0',                          'TRUE',  '000001.000009.000000(1)'),\n                   ('1.10.0',                         'TRUE',  '000001.000010.000000(1)'),\n                   ('1.11.0',                         'TRUE',  '000001.000011.000000(1)'),\n                   -- https:\/\/semver.org\/#spec-item-9\n                   ('1.0.0-alpha',                    'TRUE',  '000001.000000.000000(0)-alpha'),\n                   ('1.0.0-alpha.1',                  'TRUE',  '000001.000000.000000(0)-alpha.000001'),\n                   ('1.0.0-0.3.7',                    'TRUE',  '000001.000000.000000(0)-000000.000003.000007'),\n                   ('1.0.0-x.7.z.92',                 'TRUE',  '000001.000000.000000(0)-x.000007.z.000092'),\n                   ('1.0.0-x-y-z.--',                 'TRUE',  '000001.000000.000000(0)-x-y-z.--'),\n                   -- https:\/\/semver.org\/#spec-item-10\n                   ('1.0.0-alpha+001',                'TRUE',  '000001.000000.000000(0)-alpha'),\n                   ('1.0.0+20130313144700',           'TRUE',  '000001.000000.000000(1)'),\n                   ('1.0.0-beta+exp.sha.5114f85',     'TRUE',  '000001.000000.000000(0)-beta'),\n                   ('1.0.0+21AF26D3----117B344092BD', 'TRUE',  '000001.000000.000000(1)'),\n                   -- https:\/\/semver.org\/#spec-item-11\n                   ('1.0.0',                          'TRUE',  '000001.000000.000000(1)'),\n                   ('2.0.0',                          'TRUE',  '000002.000000.000000(1)'),\n                   ('2.1.0',                          'TRUE',  '000002.000001.000000(1)'),\n                   ('2.1.1',                          'TRUE',  '000002.000001.000001(1)'),\n                   ('1.0.0-alpha',                    'TRUE',  '000001.000000.000000(0)-alpha'),\n                   ('1.0.0-alpha.1',                  'TRUE',  '000001.000000.000000(0)-alpha.000001'),\n                   ('1.0.0-alpha.beta',               'TRUE',  '000001.000000.000000(0)-alpha.beta'),\n                   ('1.0.0-beta',                     'TRUE',  '000001.000000.000000(0)-beta'),\n                   ('1.0.0-beta.2',                   'TRUE',  '000001.000000.000000(0)-beta.000002'),\n                   ('1.0.0-beta.11',                  'TRUE',  '000001.000000.000000(0)-beta.000011'),\n                   ('1.0.0-rc.1',                     'TRUE',  '000001.000000.000000(0)-rc.000001'),\n                   --invalid\n                   ('01.0.0',                         'FALSE', null),\n                   ('1.00.0',                         'FALSE', null),\n                   ('1.0.00',                         'FALSE', null),\n                   ('1.0.x',                          'FALSE', null)\n                ) as t(input_col, test_check, test_order);\n      ut.expect(c_actual).to_equal(c_expected).join_by('INPUT_COL');\n   end test_app_semantic_version;\nend test_app_domains;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">package<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">test_app_domains<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%suite<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">procedure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">test_app_semantic_version<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> test_app_domains;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">package body<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">test_app_domains<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">procedure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">test_app_semantic_version<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      c_actual   sys_refcursor;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      c_expected sys_refcursor;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">open<\/span><span style=\"color: #D4D4D4\"> c_actual <\/span><span style=\"color: #C586C0\">for<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> input_col,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(domain_check(app_semantic_version, input_col)) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> test_check,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">when<\/span><span style=\"color: #D4D4D4\"> domain_check(app_semantic_version, input_col) <\/span><span style=\"color: #569CD6\">then<\/span><span style=\"color: #D4D4D4\"> domain_order(<\/span><span style=\"color: #DCDCAA\">cast<\/span><span style=\"color: #D4D4D4\">(input_col <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> app_semantic_version)) <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> test_order<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">values<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.9.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.10.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.11.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-9<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.1&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-0.3.7&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-x.7.z.92&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-x-y-z.--&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-10<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha+001&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0+20130313144700&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta+exp.sha.5114f85&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0+21AF26D3----117B344092BD&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-11<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.0.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.1.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.1.1&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.1&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.2&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.11&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-rc.1&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- invalid<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;01.0.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.00.0&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.00&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.x&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                ) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> t(input_col);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">open<\/span><span style=\"color: #D4D4D4\"> c_expected <\/span><span style=\"color: #C586C0\">for<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">values<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.9.0&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000009.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.10.0&#39;<\/span><span style=\"color: #D4D4D4\">,                         <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000010.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.11.0&#39;<\/span><span style=\"color: #D4D4D4\">,                         <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000011.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-9<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha&#39;<\/span><span style=\"color: #D4D4D4\">,                    <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.1&#39;<\/span><span style=\"color: #D4D4D4\">,                  <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha.000001&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-0.3.7&#39;<\/span><span style=\"color: #D4D4D4\">,                    <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-000000.000003.000007&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-x.7.z.92&#39;<\/span><span style=\"color: #D4D4D4\">,                 <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-x.000007.z.000092&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-x-y-z.--&#39;<\/span><span style=\"color: #D4D4D4\">,                 <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-x-y-z.--&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-10<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha+001&#39;<\/span><span style=\"color: #D4D4D4\">,                <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0+20130313144700&#39;<\/span><span style=\"color: #D4D4D4\">,           <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta+exp.sha.5114f85&#39;<\/span><span style=\"color: #D4D4D4\">,     <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0+21AF26D3----117B344092BD&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">-- https:\/\/semver.org\/#spec-item-11<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.0.0&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000002.000000.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.1.0&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000002.000001.000000(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;2.1.1&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000002.000001.000001(1)&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha&#39;<\/span><span style=\"color: #D4D4D4\">,                    <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.1&#39;<\/span><span style=\"color: #D4D4D4\">,                  <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha.000001&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-alpha.beta&#39;<\/span><span style=\"color: #D4D4D4\">,               <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-alpha.beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta&#39;<\/span><span style=\"color: #D4D4D4\">,                     <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.2&#39;<\/span><span style=\"color: #D4D4D4\">,                   <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-beta.000002&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.11&#39;<\/span><span style=\"color: #D4D4D4\">,                  <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-beta.000011&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.0-rc.1&#39;<\/span><span style=\"color: #D4D4D4\">,                     <\/span><span style=\"color: #CE9178\">&#39;TRUE&#39;<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #CE9178\">&#39;000001.000000.000000(0)-rc.000001&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   <\/span><span style=\"color: #6A9955\">--invalid<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;01.0.0&#39;<\/span><span style=\"color: #D4D4D4\">,                         <\/span><span style=\"color: #CE9178\">&#39;FALSE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.00.0&#39;<\/span><span style=\"color: #D4D4D4\">,                         <\/span><span style=\"color: #CE9178\">&#39;FALSE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.00&#39;<\/span><span style=\"color: #D4D4D4\">,                         <\/span><span style=\"color: #CE9178\">&#39;FALSE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                   (<\/span><span style=\"color: #CE9178\">&#39;1.0.x&#39;<\/span><span style=\"color: #D4D4D4\">,                          <\/span><span style=\"color: #CE9178\">&#39;FALSE&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                ) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> t(input_col, test_check, test_order);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(c_actual).to_equal(c_expected).join_by(<\/span><span style=\"color: #CE9178\">&#39;INPUT_COL&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> test_app_semantic_version;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> test_app_domains;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Package TEST_APP_DOMAINS compiled\n\n\nPackage Body TEST_APP_DOMAINS compiled \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Package TEST_APP_DOMAINS compiled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Package Body TEST_APP_DOMAINS compiled <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The test compares the cursors for the actual and expected results. <\/p>\n\n\n\n<p>You will get a compile error for the package body if you do not have the utPLSQL framework installed on your database instance. See the <a href=\"https:\/\/www.utplsql.org\/utPLSQL\/latest\/userguide\/install.html\">utPLSQL installation guide<\/a> for information on how to install utPLSQL. It&#8217;s quite simple and works on an Oracle Database 23ai.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"4_2_run_test\">4.2 Run Test<\/h5>\n\n\n\n<p>Now let&#8217;s run the test.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">5) run utPLSQL test<\/span><span role=\"button\" tabindex=\"0\" data-code=\"set serveroutput on size unlimited;\nexec ut.run;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> serveroutput <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> size unlimited;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">exec<\/span><span style=\"color: #D4D4D4\"> ut.run;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"test_app_domains\n  test_app_semantic_version [.087 sec] (FAILED - 1)\n \nFailures:\n \n  1) test_app_semantic_version\n      Actual: refcursor [ count = 27 ] was expected to equal: refcursor [ count = 27 ]\n      Diff:\n      Rows: [ 30 differences, showing first 20 ]\n        PK &lt;INPUT_COL&gt;1.9.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000009.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.9.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000009.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.10.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000010.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.10.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000010.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.11.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000011.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.11.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000011.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha.000001&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha.000001&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-0.3.7&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-0.3.7&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-000000.000003.000007&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-x.7.z.92&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-x.7.z.92&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-x.000007.z.000092&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-x-y-z.--&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-x-y-z.--&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-x-y-z.--&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha+001&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha+001&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0+20130313144700&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0+20130313144700&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-beta+exp.sha.5114f85&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_CHECK&gt;FALSE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER\/&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-beta+exp.sha.5114f85&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_CHECK&gt;TRUE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER&gt;000001.000000.000000(0)-beta&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0+21AF26D3----117B344092BD&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_CHECK&gt;FALSE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER\/&gt;\n        PK &lt;INPUT_COL&gt;1.0.0+21AF26D3----117B344092BD&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_CHECK&gt;TRUE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.0.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.0.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000000.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.1.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000001.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.1.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000001.000000(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.1.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000001.000001&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;2.1.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000001.000001(1)&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;\n        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0[...]\n      at &quot;DEMO42.TEST_APP_DOMAINS.TEST_APP_SEMANTIC_VERSION&quot;, line 80 ut.expect(c_actual).to_equal(c_expected).join_by('INPUT_COL');\n       \nFinished in .091311 seconds\n1 tests, 1 failed, 0 errored, 0 disabled, 0 warning(s)\n \n\n\nPL\/SQL procedure successfully completed.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">test_app_domains<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  test_app_semantic_version [.087 sec] (FAILED - 1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Failures:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  1) test_app_semantic_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      Actual: refcursor [ count = 27 ] was expected to equal: refcursor [ count = 27 ]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      Diff:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      Rows: [ 30 differences, showing first 20 ]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.9.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000009.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.9.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000009.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.10.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000010.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.10.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000010.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.11.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000011.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.11.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000011.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha.000001&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha.000001&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-0.3.7&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-0.3.7&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-000000.000003.000007&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-x.7.z.92&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-x.7.z.92&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-x.000007.z.000092&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-x-y-z.--&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-x-y-z.--&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-x-y-z.--&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha+001&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha+001&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0)-alpha&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0+20130313144700&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0+20130313144700&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-beta+exp.sha.5114f85&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_CHECK&gt;FALSE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-beta+exp.sha.5114f85&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_CHECK&gt;TRUE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER&gt;000001.000000.000000(0)-beta&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0+21AF26D3----117B344092BD&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_CHECK&gt;FALSE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0+21AF26D3----117B344092BD&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_CHECK&gt;TRUE&lt;\/TEST_CHECK&gt;&lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.0.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.0.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000000.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.1.0&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000001.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.1.0&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000001.000000(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.1.1&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000002.000001.000001&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;2.1.1&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000002.000001.000001(1)&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Actual:   &lt;TEST_ORDER&gt;000001.000000.000000&lt;\/TEST_ORDER&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        PK &lt;INPUT_COL&gt;1.0.0-alpha&lt;\/INPUT_COL&gt; - Expected: &lt;TEST_ORDER&gt;000001.000000.000000(0[...]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      at &quot;DEMO42.TEST_APP_DOMAINS.TEST_APP_SEMANTIC_VERSION&quot;, line 80 ut.expect(c_actual).to_equal(c_expected).join_by(&#39;INPUT_COL&#39;);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Finished in .091311 seconds<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">1 tests, 1 failed, 0 errored, 0 disabled, 0 warning(s)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/SQL procedure successfully completed.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The highlighted lines for <code>1.0.0-alpha+001<\/code> explain the problems with our current implementation, which are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Missing support for pre-release labels (<code>-alpha<\/code>)<\/li>\n\n\n\n<li>Missing support for build metadata (<code>+001<\/code>, leading zeros are allowed and preserved)<\/li>\n\n\n\n<li>Missing precedence handling between releases and pre-releases (releases <code>(1)<\/code> are newer than pre-releases <code>(0)<\/code>)<\/li>\n\n\n\n<li>Missing precedence handling for pre-releases (numeric qualifiers to be compared numerically)<\/li>\n\n\n\n<li>Missing precedence handling for build metadata (to be ignored)<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5_fix\">5. Fix<\/h2>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"5_1_drop_domain\">5.1 Drop domain<\/h5>\n\n\n\n<p>Before deploying a new version of the domain, we have to drop the existing one. <code>alter domain<\/code> is not applicable because we need to change the length of the data type and a <code>create or replace<\/code> syntax variant does not exist for domains.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">6) drop domain<\/span><span role=\"button\" tabindex=\"0\" data-code=\"drop domain if exists app_semantic_version;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">drop<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_semantic_version;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Error starting at line : 1 in command -\ndrop domain if exists app_semantic_version\nError report -\nORA-11502: The domain APP_SEMANTIC_VERSION to be dropped has dependent objects.\n\nhttps:\/\/docs.oracle.com\/error-help\/db\/ora-11502\/11502. 0000 -  &quot;The domain %s to be dropped has dependent objects.&quot;\n*Cause:    An attempt is made to drop a domain with dependent objects.\n*Action:   Drop the domain using the FORCE mode\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Error starting at line : 1 in command -<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">drop domain if exists app_semantic_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Error report -<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ORA-11502: The domain APP_SEMANTIC_VERSION to be dropped has dependent objects.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">https:\/\/docs.oracle.com\/error-help\/db\/ora-11502\/11502. 0000 -  &quot;The domain %s to be dropped has dependent objects.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Cause:    An attempt is made to drop a domain with dependent objects.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Action:   Drop the domain using the FORCE mode<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Okay, that didn&#8217;t work, but the error message is good. It lets us know what to do.<\/p>\n\n\n\n<p>So let&#8217;s try again with the <code>force<\/code> option.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">7) drop domain with force option<\/span><span role=\"button\" tabindex=\"0\" data-code=\"drop domain if exists app_semantic_version force;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">drop<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_semantic_version <\/span><span style=\"color: #569CD6\">force<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Domain APP_SEMANTIC_VERSION dropped.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Domain APP_SEMANTIC_VERSION dropped.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"5_2_recreate_domain\">5.2 Recreate domain<\/h5>\n\n\n\n<p>Now we can deploy the fixed variant of the domain.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">8) recreate domain<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create domain if not exists app_semantic_version\n   as varchar2(60 byte) strict\n   -- valid examples: '0.13.0', '23.5.0', '123456.789012.345678'\n   -- valid pre-release examples: '1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-0.3.7', '1.0.0-x.7.z.92'\n   -- valid build metadata examples: '1.0.0+20130313144700', '1.0.0-beta+exp.sha.5114f85'\n   -- use suggested regex from https:\/\/semver.org\/spec\/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string without non-capturing groups (?:)\n   constraint app_semantic_version_has_major_minor_patch_ck\n      check (regexp_like(app_semantic_version, '^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-((0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$'))\n   -- add leading zeroes to major, minor, patch and numeric qualifiers in pre-release for sorting (normalized semantic version)\n   -- supports up to 6 digits for major, minor, patch and numeric qualifiers in pre-release\n   order to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 1)), 'FM000000')\n      || '.' || to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 2)), 'FM000000')\n      || '.' || to_char(to_number(regexp_substr(app_semantic_version, '\\d+', 1, 3)), 'FM000000')\n      -- sort pre-release versions (0) before final versions (1)\n      -- build metadata is ignored for sorting, they have the same precedence according to the specification\n      || case\n            when instr(app_semantic_version, '-') &gt; 0\n               and (instr(app_semantic_version, '+') = 0 or instr(app_semantic_version, '-') &lt; instr(app_semantic_version, '+'))\n            then\n               -- sort pre-release according the qualifiers after the hyphen, ignoring build metadata, add leading zeroes to qualifiers starting with a number\n               '(0)' || regexp_replace( --  workaround part 2: remove superfluous leading zeroes\n                           regexp_replace( -- workaround part 1: add 6 leading zeroes to numeric qualifiers\n                              regexp_replace( -- remove build metadata\n                                 substr(app_semantic_version, instr(app_semantic_version, '-')),\n                                 '\\+.+$',\n                                 null\n                              ),\n                              '(\\.|\\-|^)(\\d{1,6})',\n                              '\\1@000000\\2@' -- workaround since \\2 in lpad, to_char is not evaluated before calling the function\n                           ),\n                           '@[0]+(\\d{6})@',\n                           '\\1'\n                        )\n            else\n               '(1)'\n         end;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> domain <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">exists<\/span><span style=\"color: #D4D4D4\"> app_semantic_version<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">60<\/span><span style=\"color: #D4D4D4\"> byte) strict<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- valid examples: &#39;0.13.0&#39;, &#39;23.5.0&#39;, &#39;123456.789012.345678&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- valid pre-release examples: &#39;1.0.0-alpha&#39;, &#39;1.0.0-alpha.1&#39;, &#39;1.0.0-0.3.7&#39;, &#39;1.0.0-x.7.z.92&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- valid build metadata examples: &#39;1.0.0+20130313144700&#39;, &#39;1.0.0-beta+exp.sha.5114f85&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- use suggested regex from https:\/\/semver.org\/spec\/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string without non-capturing groups (?:)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">constraint<\/span><span style=\"color: #D4D4D4\"> app_semantic_version_has_major_minor_patch_ck<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">check<\/span><span style=\"color: #D4D4D4\"> (regexp_like(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-((0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$&#39;<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- add leading zeroes to major, minor, patch and numeric qualifiers in pre-release for sorting (normalized semantic version)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">-- supports up to 6 digits for major, minor, patch and numeric qualifiers in pre-release<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   order <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;\\d+&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #CE9178\">&#39;FM000000&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #6A9955\">-- sort pre-release versions (0) before final versions (1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #6A9955\">-- build metadata is ignored for sorting, they have the same precedence according to the specification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #C586C0\">case<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">when<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">instr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\">) &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #DCDCAA\">instr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;+&#39;<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">or<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">instr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\">) &lt; <\/span><span style=\"color: #DCDCAA\">instr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;+&#39;<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #6A9955\">-- sort pre-release according the qualifiers after the hyphen, ignoring build metadata, add leading zeroes to qualifiers starting with a number<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #CE9178\">&#39;(0)&#39;<\/span><span style=\"color: #D4D4D4\"> || regexp_replace( <\/span><span style=\"color: #6A9955\">--  workaround part 2: remove superfluous leading zeroes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                           regexp_replace( <\/span><span style=\"color: #6A9955\">-- workaround part 1: add 6 leading zeroes to numeric qualifiers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                              regexp_replace( <\/span><span style=\"color: #6A9955\">-- remove build metadata<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                 <\/span><span style=\"color: #DCDCAA\">substr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #DCDCAA\">instr<\/span><span style=\"color: #D4D4D4\">(app_semantic_version, <\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\">)),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                 <\/span><span style=\"color: #CE9178\">&#39;\\+.+$&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                                 <\/span><span style=\"color: #569CD6\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                              ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                              <\/span><span style=\"color: #CE9178\">&#39;(\\.|\\-|^)(\\d{1,6})&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                              <\/span><span style=\"color: #CE9178\">&#39;\\1@000000\\2@&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #6A9955\">-- workaround since \\2 in lpad, to_char is not evaluated before calling the function<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                           ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                           <\/span><span style=\"color: #CE9178\">&#39;@[0]+(\\d{6})@&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                           <\/span><span style=\"color: #CE9178\">&#39;\\1&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #CE9178\">&#39;(1)&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Domain APP_SEMANTIC_VERSION created.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Domain APP_SEMANTIC_VERSION created.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The details of the fix are not so important, besides the fact that the data type changed from <code>varchar2(20 bytes)<\/code> to <code>varchar2(60 bytes)<\/code>.<\/p>\n\n\n\n<p>This variant should fully support <a href=\"https:\/\/semver.org\/spec\/v2.0.0.html\">Semantic Versioning 2.0<\/a> as long as numeric qualifiers do not require more than 6 digits. This is good enough for my use case.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"5_3_re_test\">5.3 Re-test<\/h5>\n\n\n\n<p>It&#8217;s now time to re-run the previously failed utPLSQL test.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">9) re-run utPLSQL test<\/span><span role=\"button\" tabindex=\"0\" data-code=\"set serveroutput on size unlimited;\nexec ut.run;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> serveroutput <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">size<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">unlimited<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">exec<\/span><span style=\"color: #D4D4D4\"> ut.run;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"test_app_domains\n  test_app_semantic_version [.02 sec]\n \nFinished in .021919 seconds\n1 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)\n \n\n\nPL\/SQL procedure successfully completed.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">test_app_domains<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  test_app_semantic_version [.02 sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Finished in .021919 seconds<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">1 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/SQL procedure successfully completed.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Looks good.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"5_4_check_table\">5.4 Check Table<\/h5>\n\n\n\n<p>Now let&#8217;s look at the structure of the <code>app_files<\/code> table.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">10) describe app_files before change<\/span><span role=\"button\" tabindex=\"0\" data-code=\"desc app_files\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Name         Null?    Type                                    \n------------ -------- --------------------------------------- \nFILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER      \nFILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME \nFILE_VERSION NOT NULL VARCHAR2(20)                            \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Name         Null?    Type                                    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------ -------- --------------------------------------- <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">FILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER      <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">FILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">FILE_VERSION NOT NULL VARCHAR2(20)                            <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The <code>file_version<\/code> column has a length of <code>20<\/code> instead of <code>60<\/code> bytes, and the association with the <code>app_semantic_version<\/code> domain is missing.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"5_5_modify_table\">5.5 Modify Table<\/h5>\n\n\n\n<p>We can fix the column length and associate the column with a domain in one go.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">11) modify table app_files and describe it<\/span><span role=\"button\" tabindex=\"0\" data-code=\"alter table app_files\n   modify (file_version varchar2(60 byte) domain app_semantic_version);\n\ndesc app_files\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">alter<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   modify (file_version <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">60<\/span><span style=\"color: #D4D4D4\"> byte) domain app_semantic_version);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"Table APP_FILES altered.\n\nName         Null?    Type                                     \n------------ -------- ---------------------------------------- \nFILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER       \nFILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME  \nFILE_VERSION NOT NULL VARCHAR2(60) DOMAIN APP_SEMANTIC_VERSION                        \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Table APP_FILES altered.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Name         Null?    Type                                     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------ -------- ---------------------------------------- <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">FILE_ID      NOT NULL RAW(16 BYTE) DOMAIN APP_IDENTIFIER       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">FILE_NAME    NOT NULL VARCHAR2(128 CHAR) DOMAIN APP_FILE_NAME  <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">FILE_VERSION NOT NULL VARCHAR2(60) DOMAIN APP_SEMANTIC_VERSION                        <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This looks good and was quite easy.<\/p>\n\n\n\n<p>Let&#8217;s query the data in this table using the new domain variant.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">12) query app_files<\/span><span role=\"button\" tabindex=\"0\" data-code=\"column file_name format a9\ncolumn file_version format a12\ncolumn file_version_order format a25\nselect domain_display(file_id) as file_id,\n       file_name,\n       file_version,\n       domain_order(file_version) as file_version_order\n  from app_files\n order by file_name, file_version_order desc;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_name format a9<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_version format a12<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_version_order format a25<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> domain_display(file_id) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_version,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       domain_order(file_version) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_version_order<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">order by<\/span><span style=\"color: #D4D4D4\"> file_name, file_version_order <\/span><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"FILE_ID                              FILE_NAME FILE_VERSION FILE_VERSION_ORDER       \n------------------------------------ --------- ------------ -------------------------\n29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0        000002.000000.000000(1)  \n29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0       000001.000011.000000(1)  \n29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0       000001.000010.000000(1)  \n29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0        000001.000009.000000(1)  \n29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42       000000.000000.000042(1)  \n29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7        000000.000000.000007(1)  \n\n6 rows selected. \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">FILE_ID                              FILE_NAME FILE_VERSION FILE_VERSION_ORDER       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------------------------------ --------- ------------ -------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0        000002.000000.000000(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0       000001.000011.000000(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0       000001.000010.000000(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0        000001.000009.000000(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42       000000.000000.000042(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7        000000.000000.000007(1)  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">6 rows selected. <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The only visible change is the release version indicator &#8211;<code>(1)<\/code> &#8211; at the end of the <code>file_version_order<\/code> column. We need it when we have pre-release versions to determine the correct order.<\/p>\n\n\n\n<p>Let&#8217;s add some pre-release versions and versions with build metadata and query the table again.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">13) insert pre-release versions and re-query<\/span><span role=\"button\" tabindex=\"0\" data-code=\"insert into app_files\n   (file_name, file_version)\nvalues\n   ('file3.txt', '1.0.0-beta'),\n   ('file3.txt', '1.0.0-beta.2'),\n   ('file3.txt', '1.0.0-beta.11.2.3.4'),\n   ('file3.txt', '1.0.0-beta+exp.sha.5114f85'),\n   ('file3.txt', '1.0.0+21AF26D3----117B344092BD');\n\ncolumn file_name format a9\ncolumn file_version format a30\ncolumn file_version_order format a57\nselect domain_display(file_id) as file_id,\n       file_name,\n       file_version,\n       domain_order(file_version) as file_version_order\n  from app_files\n order by file_name, file_version_order desc;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">insert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">into<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   (file_name, file_version)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">values<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file3.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file3.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.2&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file3.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta.11.2.3.4&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file3.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.0.0-beta+exp.sha.5114f85&#39;<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   (<\/span><span style=\"color: #CE9178\">&#39;file3.txt&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;1.0.0+21AF26D3----117B344092BD&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_name format a9<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_version format a30<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">column<\/span><span style=\"color: #D4D4D4\"> file_version_order format a57<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> domain_display(file_id) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       file_version,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       domain_order(file_version) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> file_version_order<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">order by<\/span><span style=\"color: #D4D4D4\"> file_name, file_version_order <\/span><span style=\"color: #569CD6\">desc<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"5 rows inserted.\n\n\nFILE_ID                              FILE_NAME FILE_VERSION                   FILE_VERSION_ORDER                                       \n------------------------------------ --------- ------------------------------ ---------------------------------------------------------\n29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0                          000002.000000.000000(1)                                  \n29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0                         000001.000011.000000(1)                                  \n29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0                         000001.000010.000000(1)                                  \n29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0                          000001.000009.000000(1)                                  \n29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42                         000000.000000.000042(1)                                  \n29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7                          000000.000000.000007(1)                                  \n29fb5aeb-44d7-39e2-e063-03e0a8c01f4e file3.txt 1.0.0+21AF26D3----117B344092BD 000001.000000.000000(1)                                  \n29fb5aeb-44d5-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta.11.2.3.4            000001.000000.000000(0)-beta.000011.000002.000003.000004 \n29fb5aeb-44d4-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta.2                   000001.000000.000000(0)-beta.000002                      \n29fb5aeb-44d3-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta                     000001.000000.000000(0)-beta                             \n29fb5aeb-44d6-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta+exp.sha.5114f85     000001.000000.000000(0)-beta                             \n\n11 rows selected. \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">5 rows inserted.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">FILE_ID                              FILE_NAME FILE_VERSION                   FILE_VERSION_ORDER                                       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">------------------------------------ --------- ------------------------------ ---------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c7-4b4d-e063-03e0a8c091f8 file1.txt 2.0.0                          000002.000000.000000(1)                                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c6-4b4d-e063-03e0a8c091f8 file1.txt 1.11.0                         000001.000011.000000(1)                                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c5-4b4d-e063-03e0a8c091f8 file1.txt 1.10.0                         000001.000010.000000(1)                                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c4-4b4d-e063-03e0a8c091f8 file1.txt 1.9.0                          000001.000009.000000(1)                                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c9-4b4d-e063-03e0a8c091f8 file2.txt 0.0.42                         000000.000000.000042(1)                                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">29ed8fd9-57c8-4b4d-e063-03e0a8c091f8 file2.txt 0.0.7                          000000.000000.000007(1)                                  <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">29fb5aeb-44d7-39e2-e063-03e0a8c01f4e file3.txt 1.0.0+21AF26D3----117B344092BD 000001.000000.000000(1)                                  <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">29fb5aeb-44d5-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta.11.2.3.4            000001.000000.000000(0)-beta.000011.000002.000003.000004 <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">29fb5aeb-44d4-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta.2                   000001.000000.000000(0)-beta.000002                      <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">29fb5aeb-44d3-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta                     000001.000000.000000(0)-beta                             <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">29fb5aeb-44d6-39e2-e063-03e0a8c01f4e file3.txt 1.0.0-beta+exp.sha.5114f85     000001.000000.000000(0)-beta                             <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"><\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">11 rows selected. <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Look at the five highlighted rows. The pre-release labels are considered in the <code>file_version_order<\/code> column but the build metadata is ignored.<\/p>\n\n\n\n<p>Now we can easily determine the latest version of a file.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">14) query latest versions of all files<\/span><span role=\"button\" tabindex=\"0\" data-code=\"select file_Name, file_version as latest_file_version\n  from (\n          select file_name,\n                 file_version,\n                 domain_order(file_version) as current_version,\n                 max(domain_order(file_version)) over (partition by file_name) as max_version\n            from app_files\n       )\n where current_version = max_version\n order by file_name;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> file_Name, file_version <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> latest_file_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> file_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                 file_version,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                 domain_order(file_version) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> current_version,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                 <\/span><span style=\"color: #DCDCAA\">max<\/span><span style=\"color: #D4D4D4\">(domain_order(file_version)) <\/span><span style=\"color: #569CD6\">over<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">partition by<\/span><span style=\"color: #D4D4D4\"> file_name) <\/span><span style=\"color: #569CD6\">as<\/span><span style=\"color: #D4D4D4\"> max_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> app_files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">where<\/span><span style=\"color: #D4D4D4\"> current_version = max_version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">order by<\/span><span style=\"color: #D4D4D4\"> file_name;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" data-code=\"FILE_NAME LATEST_FILE_VERSION                                         \n--------- ------------------------------------------------------------\nfile1.txt 2.0.0                                                       \nfile2.txt 0.0.42                                                      \nfile3.txt 1.0.0+21AF26D3----117B344092BD                                     \" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">FILE_NAME LATEST_FILE_VERSION                                         <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">--------- ------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">file1.txt 2.0.0                                                       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">file2.txt 0.0.42                                                      <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">file3.txt 1.0.0+21AF26D3----117B344092BD                                     <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The domain nicely hides the implementation details of the semantic versioning precedence rules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6_alternatives_to_domains\">6. Alternatives to Domains<\/h2>\n\n\n\n<p>The following table shows the domain features and their alternatives within the Oracle Database.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Domain Feature<\/th><th class=\"has-text-align-left\" data-align=\"left\">Alternative<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Data type of a domain column<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Data type of a table column<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Enums<\/td><td class=\"has-text-align-left\" data-align=\"left\">\ud83e\udd14 Lookup table<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Constraint on single-column domain<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Table constraint<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Constraint on multi-column domain<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Table constraint<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Flexible domain<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Table constraint<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Validate JSON column against a schema<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Table constraint<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u274c Collation<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u274c Table column collation<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Annotation<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Table column annotation<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Display expression<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Function (standalone, package, type)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Order expression<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u2705 Function (standalone, package, type)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The emojis have the following meanings:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u2705 A change is possible without impacting the underlying table\/data (e.g. <code>alter domain<\/code> is applicable)<\/li>\n\n\n\n<li>\ud83e\udd14 A change might have an impact on the underlying table\/data (e.g. removing\/adding enum item)<\/li>\n\n\n\n<li>\u274c A change will have an impact on the underlying table\/data (e.g. <code>alter table<\/code> or data migration)<\/li>\n<\/ul>\n\n\n\n<p>The main difference between the domain features and their alternatives is that domains provide an abstraction in a standardised way. This should make the models easier to understand and therefore easier to maintain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7_conclusion\">7. Conclusion<\/h2>\n\n\n\n<p>A tough part of evolving data structures is changing data types. Domains neither simplify nor complicate this. You only use an alternative series of statements for a change. <\/p>\n\n\n\n<p>However, reassociating domains with columns can become tedious for domains used in many columns. It&#8217;s a good idea to save the usage before dropping a domain. This is certainly a useful area for annotations and helper scripts. Perhaps future versions of the Oracle Database will allow us to disable domain associations instead of dropping them. Similar to constraints. This would be very helpful in preventing the loss of important information and would relieve us of the burden of managing additional metadata.<\/p>\n\n\n\n<p>Furthermore, the lack of support for domains in PL\/SQL or virtual columns limits its usefulness. Hopefully, future versions will address these shortcomings.<\/p>\n\n\n\n<p>Nevertheless, I like the idea of domains and will try to apply the following principles in new projects:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use strict single-column domains instead of raw data types in tables whenever possible. This ensures the consistent use of data types (e.g., for identifiers, names, descriptions, etc.).<\/li>\n\n\n\n<li>Do not use multi-column domains, as columns can only be associated with one domain. Also, do not use flexible domains (IMO we should avoid designs with discriminator columns).<\/li>\n\n\n\n<li>Favour traditional lookup tables over enums (and provide the data as part of the application). Enums become appealing for small and static reference data once domains are supported in PL\/SQL. <\/li>\n\n\n\n<li>Define a <code>display_expression<\/code> for raw and string columns, if the data should not be presented &#8220;as is&#8221; (e.g. GUID).<\/li>\n\n\n\n<li>Define an <code>order_expression<\/code> for columns that have a non-default precedence (e.g. semantic version).<\/li>\n<\/ul>\n\n\n\n<p>Ask me in two or three years whether this was a good idea.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction In my current project, I use a SQL domain to implement the formatting and precedence rules for Semantic Versioning. I started with a simple implementation covering only the most basic rules. Getting the sorting right is key in my project. It allows me to identify the latest compatible version of<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":13906,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[140,85],"class_list":["post-13743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-oracle-26ai","tag-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.\" \/>\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.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-12-24T13:57:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-04T10:44:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1067\" \/>\n\t<meta property=\"og:image:height\" content=\"800\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Evolution of a SQL Domain for Semantic Versioning\",\"datePublished\":\"2024-12-24T13:57:53+00:00\",\"dateModified\":\"2025-04-04T10:44:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/\"},\"wordCount\":1378,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/xms-tree-plain-decorated.png\",\"keywords\":[\"Oracle 26ai\",\"SQL\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/\",\"name\":\"Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/xms-tree-plain-decorated.png\",\"datePublished\":\"2024-12-24T13:57:53+00:00\",\"dateModified\":\"2025-04-04T10:44:22+00:00\",\"description\":\"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/xms-tree-plain-decorated.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/xms-tree-plain-decorated.png\",\"width\":1067,\"height\":800,\"caption\":\"Evolution of a SQL Domain for Semantic Versioning\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2024\\\/12\\\/24\\\/evolution-of-a-sql-domain-for-semantic-versioning\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Evolution of a SQL Domain for Semantic Versioning\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog","description":"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.","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.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/","og_locale":"en_US","og_type":"article","og_title":"Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog","og_description":"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.","og_url":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2024-12-24T13:57:53+00:00","article_modified_time":"2025-04-04T10:44:22+00:00","og_image":[{"width":1067,"height":800,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Evolution of a SQL Domain for Semantic Versioning","datePublished":"2024-12-24T13:57:53+00:00","dateModified":"2025-04-04T10:44:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/"},"wordCount":1378,"commentCount":0,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png","keywords":["Oracle 26ai","SQL"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/","url":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/","name":"Evolution of a SQL Domain for Semantic Versioning - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png","datePublished":"2024-12-24T13:57:53+00:00","dateModified":"2025-04-04T10:44:22+00:00","description":"SQL domains abstract column properties for use across multiple tables. I demonstrate the evolution of a domain for Semantic Versioning.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2025\/04\/xms-tree-plain-decorated.png","width":1067,"height":800,"caption":"Evolution of a SQL Domain for Semantic Versioning"},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2024\/12\/24\/evolution-of-a-sql-domain-for-semantic-versioning\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Evolution of a SQL Domain for Semantic Versioning"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/13743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=13743"}],"version-history":[{"count":57,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/13743\/revisions"}],"predecessor-version":[{"id":13801,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/13743\/revisions\/13801"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/13906"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=13743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=13743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=13743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}