Repository: ariga/atlas
Pull request #2880 (2024-06-19 12:43:14)

doc/md: edit deployments doc


Patch:
diff --git a/doc/md/atlas-schema/hcl.mdx b/doc/md/atlas-schema/hcl.mdx
index 786f0b1b..e25297d5 100644
--- a/doc/md/atlas-schema/hcl.mdx
+++ b/doc/md/atlas-schema/hcl.mdx
@@ -622,6 +622,9 @@ primary key.
 
 #### Example
 
+<Tabs>
+<TabItem label="Columns" value="columns">
+
 ```hcl
 primary_key {
   columns = [column.id]
@@ -632,7 +635,36 @@ primary_key {
 
 | Name    | Kind      | Type                     | Description                                                    |
 |---------|-----------|--------------------------|----------------------------------------------------------------|
-| columns | resource  | reference (list)         | A list of references to columns that comprise the primary key. |
+| columns | attribute | reference (list)         | A list of references to columns that comprise the primary key. |
+
+</TabItem>
+<TabItem label="Expressions" value="expr">
+
+:::info
+Note, primary key expressions are supported by ClickHouse.
+::: 
+
+```hcl
+primary_key {
+  on {
+    column = column.id
+  }
+  on {
+    expr = "c1 + c2"
+  }
+}
+```
+
+#### Properties
+
+| Name    | Kind      | Type                     | Description                                                    |
+|---------|-----------|--------------------------|----------------------------------------------------------------|
+| on      | resource  | schema.IndexPart (list)  | The index parts that comprise the index                        |
+
+</TabItem>
+</Tabs>
+
+
 
 ## Foreign Key
 
@@ -1309,6 +1341,56 @@ function "fn_return_table" {
 </TabItem>
 </Tabs>
 
+:::info <a class="sticky-anchor" id={"scope"} href={"#testing-functions"}>Testing Functions</a>
+
+Atlas testing framework allows you to write unit tests for your functions. The following example demonstrates how
+to write tests for the `positive` function defined above. For more detail, read the [schema testing docs](/testing/schema).
+
+
+<Tabs>
+<TabItem label="Simple Test" value="simple">
+
+```hcl title="schema.test.hcl"
+test "schema" "simple_test" {
+  parallel = true
+  assert {
+    sql = "SELECT positive(1)"
+  }
+  log {
+    message = "First assertion passed"
+  }
+  assert {
+    sql = <<SQL
+SELECT NOT positive(0);
+SELECT NOT positive(-1);
+SQL
+  }
+}
+```
+
+</TabItem>
+<TabItem label="Table-driven Test" value="table-driven">
+
+```hcl title="schema.test.hcl"
+test "schema" "simple_test" {
+  parallel = true
+  for_each = [
+    {input: 1, expected: "t"},
+    {input: 0, expected: "f"},
+    {input: -1, expected: "f"},
+  ]
+  exec {
+    sql = "SELECT positive(${each.value.input})"
+    output = each.value.expected
+  }
+}
+```
+
+</TabItem>
+</Tabs>
+
+:::
+
 #### Aggregate Functions
 
 The `aggregate` block defines a function that computes a single result from a set of values. Supported by
diff --git a/doc/md/cloud/deployment.mdx b/doc/md/cloud/deployment.mdx
index 3806c614..b08f274c 100644
--- a/doc/md/cloud/deployment.mdx
+++ b/doc/md/cloud/deployment.mdx
@@ -29,7 +29,7 @@ with a single command (or using popular CD tools such as Kubernetes and Terrafor
 
 ## Deploying migrations from Atlas Cloud
 
-To read the migrations directory from the [Schema Registry](https://atlasgo.io/cloud/features/registry),
+To read the migration directory from the [Schema Registry](https://atlasgo.io/cloud/features/registry),
 use the `atlas://` scheme in the migration URL as follows:
 
 ```hcl title="atlas.hcl"
@@ -79,4 +79,3 @@ runs in your cloud account. Here's a demonstration of how it looks in action:
 
 </TabItem>
 </Tabs>
-
diff --git a/doc/md/cloud/features/troubleshooting.mdx b/doc/md/cloud/features/troubleshooting.mdx
new file mode 100644
index 00000000..d545429c
--- /dev/null
+++ b/doc/md/cloud/features/troubleshooting.mdx
@@ -0,0 +1,46 @@
+---
+title: Troubleshooting Migrations
+slug: /cloud/features/troubleshooting
+---
+
+Troubleshooting and triaging failures during database migrations can be especially difficult. Errors often stem from data
+and schema changes, making it hard to identify the exact problem.
+
+When an error or migration failure occurs, it is crucial to understand what went wrong and assess the current state of
+the database.
+
+## Drill Down Analysis
+
+When reporting migration runs to Atlas Cloud, the detailed logs allow you to quickly drill down and troubleshoot
+any schema migration failures.
+
+The report shows what happened in the migration, what caused the failure, and the current state of the
+database post-deployment.
+
+For example, in the image below we can see a migration that failed due to a constraint, `number_length`, which
+was violated. This caused the migration to fail and only one of the three intended migration files was executed on
+the database.
+
+[![](https://atlasgo.io/uploads/cloud/images/gh-failed-deployment.png)](https://gh.atlasgo.cloud/dirs/4294967329/deployments/51539607581)
+
+### Database-per-Tenant Migrations
+
+In a database-per-tenant architecture, the same migration is executed on multiple databases. If a migration fails,
+the root cause of the error often involves tenant-specific data and schema changes, making it even more challenging to
+pinpoint issues.
+
+In this scenario, identifying which databases were affected and which remained unaffected is crucial to assess the impact
+and plan the next steps effectively.
+
+In the image below we can see the deployment intended to run on four different databases. The migration failed once it reached
+the third tenant, stopping the deployment entirely before reaching the last tenant's database.
+
+[![](https://atlasgo.io/uploads/cloud/images/multitenant-failed-deployment.png)](https://gh.atlasgo.cloud/dirs/4294967347/deployments/sets/94489280523)
+
+When examining the specific tenant that failed (as shown in the image below), we can see that the failure was caused by
+an attempt to create a table that already existed in the database.
+
+[![](https://atlasgo.io/uploads/cloud/images/tenant-failed-deployment.png)](https://gh.atlasgo.cloud/dirs/4294967347/deployments/51539607566)
+
+The detailed deployment reports provide clarity on migration failures, allowing for efficient resolution and minimizing
+downtime.
diff --git a/doc/md/community-edition.mdx b/doc/md/community-edition.mdx
index da7f407d..63816942 100644
--- a/doc/md/community-edition.mdx
+++ b/doc/md/community-edition.mdx
@@ -70,11 +70,3 @@ If you want to manually install the Atlas CLI, pick one of the below builds suit
 
 </TabItem>
 </Tabs>
-
-## Building from Source
-
-If you would like to build Atlas from source, run:
-
-```
-go get ariga.io/atlas/cmd/atlas
-```
\ No newline at end of file
diff --git a/doc/website/sidebars.js b/doc/website/sidebars.js
index c87c9674..304f62e5 100644
--- a/doc/website/sidebars.js
+++ b/doc/website/sidebars.js
@@ -125,6 +125,7 @@ module.exports = {
                         {type: 'doc', id: 'cloud/features/registry', label: 'Schema Registry'},
                         {type: 'doc', id: 'cloud/features/schema-docs', label: 'Schema Docs'},
                         {type: 'doc', id: 'cloud/features/pre-migration-checks', label: 'Pre-migration Checks'},
+                        {type: 'doc', id: 'cloud/features/troubleshooting', label: 'Migration Troubleshooting'},
                     ],
                 },
                 {type: 'doc', id: 'cloud/pricing', label: 'Pricing'},
diff --git a/schemahcl/context.go b/schemahcl/context.go
index 612af9ec..5790ea9f 100644
--- a/schemahcl/context.go
+++ b/schemahcl/context.go
@@ -443,11 +443,14 @@ func (t *blockDef) addChild(blk *hclsyntax.Block, depth int) {
 	if t.children == nil {
 		t.children = make(map[string]*blockDef)
 	}
-	c := &blockDef{
-		name:   blk.Type,
-		parent: t,
+	c, ok := t.children[blk.Type]
+	if !ok {
+		c = &blockDef{
+			name:   blk.Type,
+			parent: t,
+		}
+		t.children[blk.Type] = c
 	}
-	t.children[blk.Type] = c
 	// Limit depth of children to two as we do not have any
 	// case for more than this atm. e.g., table.column.
 	if depth < 2 {


Test patch:
diff --git a/doc/md/testing/migrate.mdx b/doc/md/testing/migrate.mdx
index 847ec7f9..99f7c7b4 100644
--- a/doc/md/testing/migrate.mdx
+++ b/doc/md/testing/migrate.mdx
@@ -76,7 +76,7 @@ test "migrate" "20240613061102" {
   }
   # Migrate to version 20240613061102.
   migrate {
-      to = "20240613061102"
+    to = "20240613061102"
   }
   # Verify the correctness of the data migration.
   exec {
@@ -112,7 +112,7 @@ test "migrate" "20240613061102" {
   }
   # Migrate to the tested version.
   migrate {
-      to = "20240613061102"
+    to = "20240613061102"
   }
   # Verify the correctness of the data migration.
   exec {
diff --git a/schemahcl/schemahcl_test.go b/schemahcl/schemahcl_test.go
index da49632a..f0c11629 100644
--- a/schemahcl/schemahcl_test.go
+++ b/schemahcl/schemahcl_test.go
@@ -1104,3 +1104,46 @@ baz = 1
 	require.Equal(t, 4, rs[1].Children[0].Range().Start.Line)
 	require.Equal(t, 5, rs[1].Children[0].Attrs[0].Range().Start.Line)
 }
+
+func TestExtendedBlockDef(t *testing.T) {
+	var (
+		doc struct {
+			DefaultExtension
+		}
+		b = []byte(`
+schema "public" {}
+table "users" {}
+materialized "users_view2" {
+  schema = schema.public
+  as = "SELECT * FROM script_matview_inspect.users"
+  column "id" {
+    null = false
+  }
+  column "a" {
+    null = false
+  }
+  column "b" {
+    null = false
+  }
+  primary_key {
+    columns = [column.id]
+  }
+  populate = true
+}
+materialized "users_view" {
+  schema = schema.public
+  to = table.users
+  as = "SELECT * FROM script_matview_inspect.users"
+  index "i" {
+    on {
+      expr = "a"
+    }
+  }
+  primary_key {
+    using = index.i # Not a real syntax.
+  }
+}
+`)
+	)
+	require.NoError(t, New().EvalBytes(b, &doc, nil))
+}