github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/statements/planView.spec.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import { assert } from "chai";
    12  
    13  import { cockroach } from "src/js/protos";
    14  import { FlatPlanNode, FlatPlanNodeAttribute, flattenTree, flattenAttributes } from "src/views/statements/planView";
    15  import IAttr = cockroach.sql.ExplainTreePlanNode.IAttr;
    16  import IExplainTreePlanNode = cockroach.sql.IExplainTreePlanNode;
    17  
    18  const testAttrs1: IAttr[] = [
    19    {
    20      key: "key1",
    21      value: "value1",
    22    },
    23    {
    24      key: "key2",
    25      value: "value2",
    26    },
    27  ];
    28  
    29  const testAttrs2: IAttr[] = [
    30    {
    31      key: "key3",
    32      value: "value3",
    33    },
    34    {
    35      key: "key4",
    36      value: "value4",
    37    },
    38  ];
    39  
    40  const testFlatAttrs1: FlatPlanNodeAttribute[] = [
    41    {
    42      key: "key1",
    43      values: ["value1"],
    44      warn: false,
    45    },
    46    {
    47      key: "key2",
    48      values: ["value2"],
    49      warn: false,
    50    },
    51  ];
    52  
    53  const testFlatAttrs2: FlatPlanNodeAttribute[] = [
    54    {
    55      key: "key3",
    56      values: ["value3"],
    57      warn: false,
    58    },
    59    {
    60      key: "key4",
    61      values: ["value4"],
    62      warn: false,
    63    },
    64  ];
    65  
    66  const treePlanWithSingleChildPaths: IExplainTreePlanNode = {
    67    name: "root",
    68    attrs: null,
    69    children: [
    70      {
    71        name: "single_grandparent",
    72        attrs: testAttrs1,
    73        children: [
    74          {
    75            name: "single_parent",
    76            attrs: null,
    77            children: [
    78              {
    79                name: "single_child",
    80                attrs: testAttrs2,
    81                children: [],
    82              },
    83            ],
    84          },
    85        ],
    86      },
    87    ],
    88  };
    89  
    90  const expectedFlatPlanWithSingleChildPaths: FlatPlanNode[] = [
    91    {
    92      name: "root",
    93      attrs: [],
    94      children: [],
    95    },
    96    {
    97      name: "single_grandparent",
    98      attrs: testFlatAttrs1,
    99      children: [],
   100    },
   101    {
   102      name: "single_parent",
   103      attrs: [],
   104      children: [],
   105    },
   106    {
   107      name: "single_child",
   108      attrs: testFlatAttrs2,
   109      children: [],
   110    },
   111  ];
   112  
   113  const treePlanWithChildren1: IExplainTreePlanNode = {
   114    name: "root",
   115    attrs: testAttrs1,
   116    children: [
   117      {
   118        name: "single_grandparent",
   119        attrs: testAttrs1,
   120        children: [
   121          {
   122            name: "parent_1",
   123            attrs: null,
   124            children: [
   125              {
   126                name: "single_child",
   127                attrs: testAttrs2,
   128                children: [],
   129              },
   130            ],
   131          },
   132          {
   133            name: "parent_2",
   134            attrs: null,
   135            children: [],
   136          },
   137        ],
   138      },
   139    ],
   140  };
   141  
   142  const expectedFlatPlanWithChildren1: FlatPlanNode[] = [
   143    {
   144      name: "root",
   145      attrs: testFlatAttrs1,
   146      children: [],
   147    },
   148    {
   149      name: "single_grandparent",
   150      attrs: testFlatAttrs1,
   151      children: [
   152        [
   153          {
   154            name: "parent_1",
   155            attrs: [],
   156            children: [],
   157          },
   158          {
   159            name: "single_child",
   160            attrs: testFlatAttrs2,
   161            children: [],
   162          },
   163        ],
   164        [
   165          {
   166            name: "parent_2",
   167            attrs: [],
   168            children: [],
   169          },
   170        ],
   171      ],
   172    },
   173  ];
   174  
   175  const treePlanWithChildren2: IExplainTreePlanNode = {
   176    name: "root",
   177    attrs: null,
   178    children: [
   179      {
   180        name: "single_grandparent",
   181        attrs: null,
   182        children: [
   183          {
   184            name: "single_parent",
   185            attrs: null,
   186            children: [
   187              {
   188                name: "child_1",
   189                attrs: testAttrs1,
   190                children: [],
   191              },
   192              {
   193                name: "child_2",
   194                attrs: testAttrs2,
   195                children: [],
   196              },
   197            ],
   198          },
   199        ],
   200      },
   201    ],
   202  };
   203  
   204  const expectedFlatPlanWithChildren2: FlatPlanNode[] = [
   205    {
   206      name: "root",
   207      attrs: [],
   208      children: [],
   209    },
   210    {
   211      name: "single_grandparent",
   212      attrs: [],
   213      children: [],
   214    },
   215    {
   216      name: "single_parent",
   217      attrs: [],
   218      children: [
   219        [
   220          {
   221            name: "child_1",
   222            attrs: testFlatAttrs1,
   223            children: [],
   224          },
   225        ],
   226        [
   227          {
   228            name: "child_2",
   229            attrs: testFlatAttrs2,
   230            children: [],
   231          },
   232        ],
   233      ],
   234    },
   235  ];
   236  
   237  const treePlanWithNoChildren: IExplainTreePlanNode = {
   238    name: "root",
   239    attrs: testAttrs1,
   240    children: [],
   241  };
   242  
   243  const expectedFlatPlanWithNoChildren: FlatPlanNode[] = [
   244    {
   245      name: "root",
   246      attrs: testFlatAttrs1,
   247      children: [],
   248    },
   249  ];
   250  
   251  describe("flattenTree", () => {
   252    describe("when node has children", () => {
   253      it("flattens single child paths.", () => {
   254        assert.deepEqual(
   255          flattenTree(treePlanWithSingleChildPaths),
   256          expectedFlatPlanWithSingleChildPaths,
   257        );
   258      });
   259      it("increases level if multiple children.", () => {
   260        assert.deepEqual(
   261          flattenTree(treePlanWithChildren1),
   262          expectedFlatPlanWithChildren1,
   263        );
   264        assert.deepEqual(
   265          flattenTree(treePlanWithChildren2),
   266          expectedFlatPlanWithChildren2,
   267        );
   268      });
   269    });
   270    describe("when node has no children", () => {
   271      it("returns valid flattened plan.", () => {
   272        assert.deepEqual(
   273          flattenTree(treePlanWithNoChildren),
   274          expectedFlatPlanWithNoChildren,
   275        );
   276      });
   277    });
   278  });
   279  
   280  describe("flattenAttributes", () => {
   281    describe("when all attributes have different keys", () => {
   282      it("creates array with exactly one value for each attribute", () => {
   283        const testAttrs: IAttr[] = [
   284          {
   285            key: "key1",
   286            value: "value1",
   287          },
   288          {
   289            key: "key2",
   290            value: "value2",
   291          },
   292        ];
   293        const expectedTestAttrs: FlatPlanNodeAttribute[] = [
   294          {
   295            key: "key1",
   296            values: ["value1"],
   297            warn: false,
   298          },
   299          {
   300            key: "key2",
   301            values: ["value2"],
   302            warn: false,
   303          },
   304        ];
   305  
   306        assert.deepEqual(
   307          flattenAttributes(testAttrs),
   308          expectedTestAttrs,
   309        );
   310      });
   311    });
   312    describe("when there are multiple attributes with same key", () => {
   313      it("collects values into one array for same key", () => {
   314        const testAttrs: IAttr[] = [
   315          {
   316            key: "key1",
   317            value: "key1-value1",
   318          },
   319          {
   320            key: "key2",
   321            value: "key2-value1",
   322          },
   323          {
   324            key: "key1",
   325            value: "key1-value2",
   326          },
   327        ];
   328        const expectedTestAttrs: FlatPlanNodeAttribute[] = [
   329          {
   330            key: "key1",
   331            values: ["key1-value1", "key1-value2"],
   332            warn: false,
   333          },
   334          {
   335            key: "key2",
   336            values: ["key2-value1"],
   337            warn: false,
   338          },
   339        ];
   340  
   341        assert.deepEqual(
   342          flattenAttributes(testAttrs),
   343          expectedTestAttrs,
   344        );
   345      });
   346    });
   347    describe("when attribute key/value is `spans FULL SCAN`", () => {
   348      it("sets warn to true", () => {
   349        const testAttrs: IAttr[] = [
   350          {
   351            key: "foo",
   352            value: "bar",
   353          },
   354          {
   355            key: "spans",
   356            value: "FULL SCAN",
   357          },
   358        ];
   359        const expectedTestAttrs: FlatPlanNodeAttribute[] = [
   360          {
   361            key: "foo",
   362            values: ["bar"],
   363            warn: false,
   364          },
   365          {
   366            key: "spans",
   367            values: ["FULL SCAN"],
   368            warn: true,
   369          },
   370        ];
   371  
   372        assert.deepEqual(
   373          flattenAttributes(testAttrs),
   374          expectedTestAttrs,
   375        );
   376      });
   377    });
   378    describe("when keys are unsorted", () => {
   379      it("puts table key first, and sorts remaining keys alphabetically", () => {
   380        const testAttrs: IAttr[] = [
   381          {
   382            key: "zebra",
   383            value: "foo",
   384          },
   385          {
   386            key: "table",
   387            value: "foo",
   388          },
   389          {
   390            key: "cheetah",
   391            value: "foo",
   392          },
   393          {
   394            key: "table",
   395            value: "bar",
   396          },
   397        ];
   398        const expectedTestAttrs: FlatPlanNodeAttribute[] = [
   399          {
   400            key: "table",
   401            values: ["foo", "bar"],
   402            warn: false,
   403          },
   404          {
   405            key: "cheetah",
   406            values: ["foo"],
   407            warn: false,
   408          },
   409          {
   410            key: "zebra",
   411            values: ["foo"],
   412            warn: false,
   413          },
   414        ];
   415  
   416        assert.deepEqual(
   417          flattenAttributes(testAttrs),
   418          expectedTestAttrs,
   419        );
   420      });
   421    });
   422  });