diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 825a670a7..0e11e37d5 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -16,3 +16,4 @@ - Fixed an issue with elk layouts accounting for edge labels as if they were placed on the side of the edge. [#483](https://github.com/terrastruct/d2/pull/483) - Fixed an issue where dagre layouts may not have enough spacing for all edge labels. [#484](https://github.com/terrastruct/d2/pull/484) - Fixed connections being clipped if they were at the very top or left edges of the diagram. [#493](https://github.com/terrastruct/d2/pull/493) +- Fixed edge case where style being defined in same scope as sql_table caused compiler to skip compiling sql_table. [#506](https://github.com/terrastruct/d2/issues/506) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 901f6bcee..819dae9e3 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -583,16 +583,25 @@ func (c *compiler) compileShapes(obj *d2graph.Object) { c.compileShapes(obj) } - for _, obj := range obj.ChildrenArray { - switch obj.Attributes.Shape.Value { + for i := 0; i < len(obj.ChildrenArray); i++ { + ch := obj.ChildrenArray[i] + switch ch.Attributes.Shape.Value { case d2target.ShapeClass, d2target.ShapeSQLTable: - flattenContainer(obj.Graph, obj) + flattenContainer(obj.Graph, ch) } - if obj.IDVal == "style" { - obj.Parent.Attributes.Style = obj.Attributes.Style + if ch.IDVal == "style" { + obj.Attributes.Style = ch.Attributes.Style if obj.Graph != nil { - flattenContainer(obj.Graph, obj) - removeObject(obj.Graph, obj) + flattenContainer(obj.Graph, ch) + for i := 0; i < len(obj.Graph.Objects); i++ { + if obj.Graph.Objects[i] == ch { + obj.Graph.Objects = append(obj.Graph.Objects[:i], obj.Graph.Objects[i+1:]...) + break + } + } + delete(obj.Children, ch.ID) + obj.ChildrenArray = append(obj.ChildrenArray[:i], obj.ChildrenArray[i+1:]...) + i-- } } } @@ -706,23 +715,6 @@ func (c *compiler) compileSQLTable(obj *d2graph.Object) { } } -// TODO too similar to flattenContainer, should reconcile in a refactor -func removeObject(g *d2graph.Graph, obj *d2graph.Object) { - for i := 0; i < len(obj.Graph.Objects); i++ { - if obj.Graph.Objects[i] == obj { - obj.Graph.Objects = append(obj.Graph.Objects[:i], obj.Graph.Objects[i+1:]...) - break - } - } - delete(obj.Parent.Children, obj.ID) - for i, child := range obj.Parent.ChildrenArray { - if obj == child { - obj.Parent.ChildrenArray = append(obj.Parent.ChildrenArray[:i], obj.Parent.ChildrenArray[i+1:]...) - break - } - } -} - func flattenContainer(g *d2graph.Graph, obj *d2graph.Object) { absID := obj.AbsID() diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 5923293fc..4009aa68b 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1650,6 +1650,24 @@ choo: { } }, }, + { + name: "sql-regression", + + text: `a: { + style: { + fill: lemonchiffon + } + b: { + shape: sql_table + c + } + d +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + tassert.Equal(t, 3, len(g.Objects)) + }, + }, } for _, tc := range testCases { diff --git a/testdata/d2compiler/TestCompile/sql-regression.exp.json b/testdata/d2compiler/TestCompile/sql-regression.exp.json new file mode 100644 index 000000000..1341021c7 --- /dev/null +++ b/testdata/d2compiler/TestCompile/sql-regression.exp.json @@ -0,0 +1,402 @@ +{ + "graph": { + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-10:0:87", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-9:1:86", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:3:3-9:0:85", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,1:2:7-3:3:42", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,1:2:7-1:7:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,1:2:7-1:7:12", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,1:9:14-3:2:41", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,2:4:20-2:22:38", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,2:4:20-2:8:24", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,2:4:20-2:8:24", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,2:10:26-2:22:38", + "value": [ + { + "string": "lemonchiffon", + "raw_string": "lemonchiffon" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:2:45-7:3:80", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:2:45-4:3:46", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:2:45-4:3:46", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:5:48-7:2:79", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,5:4:54-5:20:70", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,5:4:54-5:9:59", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,5:4:54-5:9:59", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,5:11:61-5:20:70", + "value": [ + { + "string": "sql_table", + "raw_string": "sql_table" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,6:4:75-6:5:76", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,6:4:75-6:5:76", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,6:4:75-6:5:76", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,8:2:83-8:3:84", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,8:2:83-8:3:84", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,8:2:83-8:3:84", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [], + "objects": [ + { + "id": "a", + "id_val": "a", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "style": { + "fill": { + "value": "lemonchiffon" + } + }, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:2:45-4:3:46", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,4:2:45-4:3:46", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "sql_table": { + "columns": [ + { + "name": { + "label": "c", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "type": { + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "constraint": "", + "reference": "" + } + ] + }, + "attributes": { + "label": { + "value": "b" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "sql_table" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,8:2:83-8:3:84", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/sql-regression.d2,8:2:83-8:3:84", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": null +}