diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index 501bb82d7..ffd49ca9c 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -6,7 +6,7 @@ For v0.0.99 we focused on X, Y and Z. Enjoy!
#### Improvements 🔧
-- Improves something or the other #9999
+- Add table columns indices in edges between SQL Tables so that layout engines can route exactly between them
#### Bugfixes 🔴
diff --git a/d2compiler/compile.go b/d2compiler/compile.go
index 895b86d75..0db0d62d4 100644
--- a/d2compiler/compile.go
+++ b/d2compiler/compile.go
@@ -680,12 +680,12 @@ func (c *compiler) compileSQLTable(obj *d2graph.Object) {
continue
}
if srcID == absID {
- // Frontend isn't aware of container IDs.
d2Col.Reference = strings.TrimPrefix(dstID, parentID+".")
- relSrc := strings.TrimPrefix(absID, parentID+".")
- e.Attributes.Label.Value = fmt.Sprintf("%s %s %s", relSrc, e.ArrowString(), d2Col.Reference)
- // removeContainer() will adjust the edge to point to the table and not inside.
- break
+ e.SrcTableColumnIndex = new(int)
+ *e.SrcTableColumnIndex = len(obj.SQLTable.Columns)
+ } else if dstID == absID {
+ e.DstTableColumnIndex = new(int)
+ *e.DstTableColumnIndex = len(obj.SQLTable.Columns)
}
}
@@ -746,6 +746,14 @@ func flattenContainer(g *d2graph.Graph, obj *d2graph.Object) {
newEdge, _ = g.Root.Connect(e.Src.AbsIDArray(), obj.AbsIDArray(), e.SrcArrow, e.DstArrow, e.Attributes.Label.Value)
}
// TODO more attributes
+ if e.SrcTableColumnIndex != nil {
+ newEdge.SrcTableColumnIndex = new(int)
+ *newEdge.SrcTableColumnIndex = *e.SrcTableColumnIndex
+ }
+ if e.DstTableColumnIndex != nil {
+ newEdge.DstTableColumnIndex = new(int)
+ *newEdge.DstTableColumnIndex = *e.DstTableColumnIndex
+ }
newEdge.Attributes.Label = e.Attributes.Label
newEdge.References = e.References
}
diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go
index 54f59d64c..c43639cb8 100644
--- a/d2compiler/compile_test.go
+++ b/d2compiler/compile_test.go
@@ -1474,6 +1474,32 @@ b`, g.Objects[0].Attributes.Label.Value)
SVP1.style.3d: true`,
expErr: `d2/testdata/d2compiler/TestCompile/3d_oval.d2:2:1: key "3d" can only be applied to squares and rectangles
`,
+ }, {
+ name: "edge_column_index",
+ text: `src: {
+ shape: sql_table
+ id: int
+ dst_id: int
+}
+
+dst: {
+ shape: sql_table
+ id: int
+ name: string
+}
+
+dst.id <-> src.dst_id
+`,
+ assertions: func(t *testing.T, g *d2graph.Graph) {
+ srcIndex := g.Edges[0].SrcTableColumnIndex
+ if srcIndex == nil || *srcIndex != 0 {
+ t.Fatalf("expected SrcTableColumnIndex to be 0, got %v", srcIndex)
+ }
+ dstIndex := g.Edges[0].DstTableColumnIndex
+ if dstIndex == nil || *dstIndex != 1 {
+ t.Fatalf("expected DstTableColumnIndex to be 1, got %v", dstIndex)
+ }
+ },
},
}
diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index aef91878f..5687608f1 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -607,6 +607,9 @@ type Edge struct {
MinWidth int `json:"minWidth"`
MinHeight int `json:"minHeight"`
+ SrcTableColumnIndex *int `json:"srcTableColumnIndex,omitempty"`
+ DstTableColumnIndex *int `json:"dstTableColumnIndex,omitempty"`
+
LabelDimensions d2target.TextDimensions `json:"label_dimensions"`
LabelPosition *string `json:"labelPosition,omitempty"`
LabelPercentage *float64 `json:"labelPercentage,omitempty"`
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index c9a1a87fc..ab7d770a9 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -831,6 +831,43 @@ a -> md -> b
+setTimeout(seconds int)
}
`,
+ }, {
+ name: "sql_tables",
+ script: `users: {
+ shape: sql_table
+ id: int
+ name: string
+ email: string
+ password: string
+ last_login: datetime
+}
+
+products: {
+ shape: sql_table
+ id: int
+ price: decimal
+ sku: string
+ name: string
+}
+
+orders: {
+ shape: sql_table
+ id: int
+ user_id: int
+ product_id: int
+}
+
+shipments: {
+ shape: sql_table
+ id: int
+ order_id: int
+ tracking_number: string
+ status: string
+}
+
+users.id <-> orders.user_id
+products.id <-> orders.product_id
+shipments.order_id <-> orders.id`,
},
}
diff --git a/e2etests/testdata/stable/sql_tables/dagre/board.exp.json b/e2etests/testdata/stable/sql_tables/dagre/board.exp.json
new file mode 100644
index 000000000..da031d9b2
--- /dev/null
+++ b/e2etests/testdata/stable/sql_tables/dagre/board.exp.json
@@ -0,0 +1,396 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "users",
+ "type": "sql_table",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 259,
+ "height": 216,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.user_id"
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "email",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "password",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "last_login",
+ "type": "datetime",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "users",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 61,
+ "labelHeight": 36
+ },
+ {
+ "id": "products",
+ "type": "sql_table",
+ "pos": {
+ "x": 319,
+ "y": 18
+ },
+ "width": 290,
+ "height": 180,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.product_id"
+ },
+ {
+ "name": "price",
+ "type": "decimal",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "sku",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "products",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 99,
+ "labelHeight": 36
+ },
+ {
+ "id": "orders",
+ "type": "sql_table",
+ "pos": {
+ "x": 357,
+ "y": 316
+ },
+ "width": 215,
+ "height": 144,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "user_id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "product_id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "orders",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36
+ },
+ {
+ "id": "shipments",
+ "type": "sql_table",
+ "pos": {
+ "x": 669,
+ "y": 18
+ },
+ "width": 293,
+ "height": 180,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "order_id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.id"
+ },
+ {
+ "name": "tracking_number",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "status",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "shipments",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 116,
+ "labelHeight": 36
+ }
+ ],
+ "connections": [
+ {
+ "id": "(users <-> orders)[0]",
+ "src": "users",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 129.5,
+ "y": 216
+ },
+ {
+ "x": 129.5,
+ "y": 256
+ },
+ {
+ "x": 174.9,
+ "y": 282.55844544095663
+ },
+ {
+ "x": 356.5,
+ "y": 348.7922272047833
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(products <-> orders)[0]",
+ "src": "products",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 464,
+ "y": 198
+ },
+ {
+ "x": 464,
+ "y": 252.4
+ },
+ {
+ "x": 464,
+ "y": 276
+ },
+ {
+ "x": 464,
+ "y": 316
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(shipments <-> orders)[0]",
+ "src": "shipments",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 815.5,
+ "y": 198
+ },
+ {
+ "x": 815.5,
+ "y": 252.4
+ },
+ {
+ "x": 766.7,
+ "y": 283
+ },
+ {
+ "x": 571.5,
+ "y": 351
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ }
+ ]
+}
diff --git a/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg
new file mode 100644
index 000000000..065687658
--- /dev/null
+++ b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg
@@ -0,0 +1,56 @@
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/sql_tables/elk/board.exp.json b/e2etests/testdata/stable/sql_tables/elk/board.exp.json
new file mode 100644
index 000000000..abc5d00bf
--- /dev/null
+++ b/e2etests/testdata/stable/sql_tables/elk/board.exp.json
@@ -0,0 +1,385 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "users",
+ "type": "sql_table",
+ "pos": {
+ "x": 46,
+ "y": 412
+ },
+ "width": 259,
+ "height": 216,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.user_id"
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "email",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "password",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "last_login",
+ "type": "datetime",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "users",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 61,
+ "labelHeight": 36
+ },
+ {
+ "id": "products",
+ "type": "sql_table",
+ "pos": {
+ "x": 15,
+ "y": 212
+ },
+ "width": 290,
+ "height": 180,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.product_id"
+ },
+ {
+ "name": "price",
+ "type": "decimal",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "sku",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "products",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 99,
+ "labelHeight": 36
+ },
+ {
+ "id": "orders",
+ "type": "sql_table",
+ "pos": {
+ "x": 405,
+ "y": 230
+ },
+ "width": 215,
+ "height": 144,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "user_id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "product_id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "orders",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36
+ },
+ {
+ "id": "shipments",
+ "type": "sql_table",
+ "pos": {
+ "x": 12,
+ "y": 12
+ },
+ "width": 293,
+ "height": 180,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0A0F25",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "order_id",
+ "type": "int",
+ "constraint": "",
+ "reference": "orders.id"
+ },
+ {
+ "name": "tracking_number",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "status",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ }
+ ],
+ "label": "shipments",
+ "fontSize": 20,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 116,
+ "labelHeight": 36
+ }
+ ],
+ "connections": [
+ {
+ "id": "(users <-> orders)[0]",
+ "src": "users",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 305,
+ "y": 520
+ },
+ {
+ "x": 355,
+ "y": 520
+ },
+ {
+ "x": 355,
+ "y": 338
+ },
+ {
+ "x": 405,
+ "y": 338
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(products <-> orders)[0]",
+ "src": "products",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 305,
+ "y": 302
+ },
+ {
+ "x": 405,
+ "y": 302
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(shipments <-> orders)[0]",
+ "src": "shipments",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "orders",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 305,
+ "y": 102
+ },
+ {
+ "x": 355,
+ "y": 102
+ },
+ {
+ "x": 355,
+ "y": 266
+ },
+ {
+ "x": 405,
+ "y": 266
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ }
+ ]
+}
diff --git a/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg b/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg
new file mode 100644
index 000000000..e20e68fe8
--- /dev/null
+++ b/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg
@@ -0,0 +1,56 @@
+
+
\ No newline at end of file
diff --git a/testdata/d2compiler/TestCompile/edge_column_index.exp.json b/testdata/d2compiler/TestCompile/edge_column_index.exp.json
new file mode 100644
index 000000000..8a9fde6d3
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/edge_column_index.exp.json
@@ -0,0 +1,559 @@
+{
+ "graph": {
+ "ast": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-13:0:123",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-4:1:48",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "src",
+ "raw_string": "src"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:5:5-4:0:47",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,1:1:8-1:17:24",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,1:1:8-1:6:13",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,1:1:8-1:6:13",
+ "value": [
+ {
+ "string": "shape",
+ "raw_string": "shape"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,1:8:15-1:17:24",
+ "value": [
+ {
+ "string": "sql_table",
+ "raw_string": "sql_table"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,2:1:26-2:8:33",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,2:1:26-2:3:28",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,2:1:26-2:3:28",
+ "value": [
+ {
+ "string": "id",
+ "raw_string": "id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,2:5:30-2:8:33",
+ "value": [
+ {
+ "string": "int",
+ "raw_string": "int"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,3:1:35-3:12:46",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,3:1:35-3:7:41",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,3:1:35-3:7:41",
+ "value": [
+ {
+ "string": "dst_id",
+ "raw_string": "dst_id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,3:9:43-3:12:46",
+ "value": [
+ {
+ "string": "int",
+ "raw_string": "int"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:0:50-10:1:99",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:0:50-6:3:53",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:0:50-6:3:53",
+ "value": [
+ {
+ "string": "dst",
+ "raw_string": "dst"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:5:55-10:0:98",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,7:1:58-7:17:74",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,7:1:58-7:6:63",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,7:1:58-7:6:63",
+ "value": [
+ {
+ "string": "shape",
+ "raw_string": "shape"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,7:8:65-7:17:74",
+ "value": [
+ {
+ "string": "sql_table",
+ "raw_string": "sql_table"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,8:1:76-8:8:83",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,8:1:76-8:3:78",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,8:1:76-8:3:78",
+ "value": [
+ {
+ "string": "id",
+ "raw_string": "id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,8:5:80-8:8:83",
+ "value": [
+ {
+ "string": "int",
+ "raw_string": "int"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,9:1:85-9:13:97",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,9:1:85-9:5:89",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,9:1:85-9:5:89",
+ "value": [
+ {
+ "string": "name",
+ "raw_string": "name"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,9:7:91-9:13:97",
+ "value": [
+ {
+ "string": "string",
+ "raw_string": "string"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:21:122",
+ "edges": [
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:21:122",
+ "src": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:7:108",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:3:104",
+ "value": [
+ {
+ "string": "dst",
+ "raw_string": "dst"
+ }
+ ]
+ }
+ },
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:4:105-12:6:107",
+ "value": [
+ {
+ "string": "id",
+ "raw_string": "id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "src_arrow": "<",
+ "dst": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:10:111-12:21:122",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:11:112-12:14:115",
+ "value": [
+ {
+ "string": "src",
+ "raw_string": "src"
+ }
+ ]
+ }
+ },
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:15:116-12:21:122",
+ "value": [
+ {
+ "string": "dst_id",
+ "raw_string": "dst_id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "dst_arrow": ">"
+ }
+ ],
+ "primary": {},
+ "value": {}
+ }
+ }
+ ]
+ },
+ "root": {
+ "id": "",
+ "id_val": "",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ }
+ }
+ },
+ "edges": [
+ {
+ "index": 0,
+ "minWidth": 0,
+ "minHeight": 0,
+ "srcTableColumnIndex": 0,
+ "dstTableColumnIndex": 1,
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "isCurve": false,
+ "src_arrow": true,
+ "dst_arrow": true,
+ "references": [
+ {
+ "map_key_edge_index": 0
+ }
+ ],
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ }
+ }
+ }
+ ],
+ "objects": [
+ {
+ "id": "src",
+ "id_val": "src",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "src",
+ "raw_string": "src"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": 0
+ },
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:10:111-12:21:122",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:11:112-12:14:115",
+ "value": [
+ {
+ "string": "src",
+ "raw_string": "src"
+ }
+ ]
+ }
+ },
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:15:116-12:21:122",
+ "value": [
+ {
+ "string": "dst_id",
+ "raw_string": "dst_id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": 0
+ }
+ ],
+ "sql_table": {
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ },
+ {
+ "name": "dst_id",
+ "type": "int",
+ "constraint": "",
+ "reference": ""
+ }
+ ]
+ },
+ "attributes": {
+ "label": {
+ "value": "src"
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": "sql_table"
+ }
+ }
+ },
+ {
+ "id": "dst",
+ "id_val": "dst",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:0:50-6:3:53",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,6:0:50-6:3:53",
+ "value": [
+ {
+ "string": "dst",
+ "raw_string": "dst"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": 0
+ },
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:7:108",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:0:101-12:3:104",
+ "value": [
+ {
+ "string": "dst",
+ "raw_string": "dst"
+ }
+ ]
+ }
+ },
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/edge_column_index.d2,12:4:105-12:6:107",
+ "value": [
+ {
+ "string": "id",
+ "raw_string": "id"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": 0
+ }
+ ],
+ "sql_table": {
+ "columns": [
+ {
+ "name": "id",
+ "type": "int",
+ "constraint": "",
+ "reference": "src.dst_id"
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "constraint": "",
+ "reference": ""
+ }
+ ]
+ },
+ "attributes": {
+ "label": {
+ "value": "dst"
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": "sql_table"
+ }
+ }
+ }
+ ]
+ },
+ "err": null
+}