@finos/legend-query-builder 4.1.2 → 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.js +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +91 -24
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.d.ts +23 -0
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.js +32 -0
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.js.map +1 -0
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.d.ts +23 -0
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.js +35 -0
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.js.map +1 -0
- package/lib/components/execution-plan/DataTypeResultTypeViewer.d.ts +21 -0
- package/lib/components/execution-plan/DataTypeResultTypeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/DataTypeResultTypeViewer.js +31 -0
- package/lib/components/execution-plan/DataTypeResultTypeViewer.js.map +1 -0
- package/lib/components/execution-plan/ExecutionPlanViewer.d.ts +10 -4
- package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
- package/lib/components/execution-plan/ExecutionPlanViewer.js +74 -62
- package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.d.ts +25 -0
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.js +47 -0
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.js.map +1 -0
- package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.d.ts +23 -0
- package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.js +31 -0
- package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.js.map +1 -0
- package/lib/components/execution-plan/ResultTypeViewer.d.ts +21 -0
- package/lib/components/execution-plan/ResultTypeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/ResultTypeViewer.js +33 -0
- package/lib/components/execution-plan/ResultTypeViewer.js.map +1 -0
- package/lib/components/execution-plan/SQLExecutionNodeViewer.d.ts +9 -1
- package/lib/components/execution-plan/SQLExecutionNodeViewer.d.ts.map +1 -1
- package/lib/components/execution-plan/SQLExecutionNodeViewer.js +12 -6
- package/lib/components/execution-plan/SQLExecutionNodeViewer.js.map +1 -1
- package/lib/components/execution-plan/SequenceExecutionNodeViewer.d.ts +23 -0
- package/lib/components/execution-plan/SequenceExecutionNodeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/SequenceExecutionNodeViewer.js +38 -0
- package/lib/components/execution-plan/SequenceExecutionNodeViewer.js.map +1 -0
- package/lib/components/execution-plan/TDSResultTypeViewer.d.ts +21 -0
- package/lib/components/execution-plan/TDSResultTypeViewer.d.ts.map +1 -0
- package/lib/components/execution-plan/TDSResultTypeViewer.js +25 -0
- package/lib/components/execution-plan/TDSResultTypeViewer.js.map +1 -0
- package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderMilestoningEditor.js +3 -3
- package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +24 -34
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +44 -11
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +4 -4
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +20 -32
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +0 -3
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +2 -25
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/execution-plan/ExecutionPlanState.d.ts +14 -1
- package/lib/stores/execution-plan/ExecutionPlanState.d.ts.map +1 -1
- package/lib/stores/execution-plan/ExecutionPlanState.js +86 -3
- package/lib/stores/execution-plan/ExecutionPlanState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +3 -0
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +11 -0
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
- package/package.json +5 -5
- package/src/components/QueryBuilderPropertyExpressionEditor.tsx +1 -2
- package/src/components/QueryBuilderResultPanel.tsx +146 -30
- package/src/components/execution-plan/AllocationExecutionNodeViewer.tsx +77 -0
- package/src/components/execution-plan/ConstantExecutionNodeViewer.tsx +82 -0
- package/src/components/execution-plan/DataTypeResultTypeViewer.tsx +52 -0
- package/src/components/execution-plan/ExecutionPlanViewer.tsx +205 -195
- package/src/components/execution-plan/FunctionParametersValidationNodeViewer.tsx +118 -0
- package/src/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.tsx +68 -0
- package/src/components/execution-plan/ResultTypeViewer.tsx +37 -0
- package/src/components/execution-plan/SQLExecutionNodeViewer.tsx +50 -19
- package/src/components/execution-plan/SequenceExecutionNodeViewer.tsx +95 -0
- package/src/components/execution-plan/TDSResultTypeViewer.tsx +59 -0
- package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +5 -8
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +32 -61
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +77 -14
- package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +6 -8
- package/src/components/filter/QueryBuilderFilterPanel.tsx +45 -73
- package/src/stores/QueryBuilderResultState.ts +1 -42
- package/src/stores/execution-plan/ExecutionPlanState.ts +142 -4
- package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +16 -0
- package/tsconfig.json +8 -0
|
@@ -14,10 +14,9 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { useEffect } from 'react';
|
|
18
18
|
import {
|
|
19
19
|
type TreeNodeContainerProps,
|
|
20
|
-
type TreeData,
|
|
21
20
|
Dialog,
|
|
22
21
|
ResizablePanelGroup,
|
|
23
22
|
ResizablePanelSplitter,
|
|
@@ -41,16 +40,13 @@ import {
|
|
|
41
40
|
PanelHeader,
|
|
42
41
|
Panel,
|
|
43
42
|
} from '@finos/legend-art';
|
|
44
|
-
import {
|
|
45
|
-
addUniqueEntry,
|
|
46
|
-
filterByType,
|
|
47
|
-
isNonNullable,
|
|
48
|
-
} from '@finos/legend-shared';
|
|
43
|
+
import { isNonNullable } from '@finos/legend-shared';
|
|
49
44
|
import {
|
|
50
45
|
ExecutionNodeTreeNodeData,
|
|
51
46
|
ExecutionPlanViewTreeNodeData,
|
|
52
47
|
EXECUTION_PLAN_VIEW_MODE,
|
|
53
48
|
type ExecutionPlanState,
|
|
49
|
+
generateExecutionNodeTreeNodeData,
|
|
54
50
|
} from '../../stores/execution-plan/ExecutionPlanState.js';
|
|
55
51
|
import { observer } from 'mobx-react-lite';
|
|
56
52
|
import {
|
|
@@ -58,225 +54,182 @@ import {
|
|
|
58
54
|
ExecutionNode,
|
|
59
55
|
SQLExecutionNode,
|
|
60
56
|
RelationalTDSInstantiationExecutionNode,
|
|
57
|
+
FunctionParametersValidationNode,
|
|
58
|
+
AllocationExecutionNode,
|
|
59
|
+
ConstantExecutionNode,
|
|
60
|
+
SequenceExecutionNode,
|
|
61
61
|
type RawExecutionPlan,
|
|
62
62
|
} from '@finos/legend-graph';
|
|
63
63
|
import { SQLExecutionNodeViewer } from './SQLExecutionNodeViewer.js';
|
|
64
|
+
import { FunctionParametersValidationNodeViewer } from './FunctionParametersValidationNodeViewer.js';
|
|
65
|
+
import { AllocationExecutionNodeViewer } from './AllocationExecutionNodeViewer.js';
|
|
66
|
+
import { ConstantExecutionNodeViewer } from './ConstantExecutionNodeViewer.js';
|
|
67
|
+
import { SequenceExecutionNodeViewer } from './SequenceExecutionNodeViewer.js';
|
|
68
|
+
import { RelationalTDSInstantiationExecutionNodeViewer } from './RelationalTDSInstantiationExecutionNodeViewer.js';
|
|
64
69
|
import {
|
|
65
70
|
CODE_EDITOR_LANGUAGE,
|
|
66
71
|
CodeEditor,
|
|
67
72
|
} from '@finos/legend-lego/code-editor';
|
|
68
73
|
import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
|
|
69
74
|
|
|
75
|
+
const EXECUTION_PLAN = 'Execution Plan';
|
|
70
76
|
/**
|
|
71
77
|
* @modularize
|
|
72
78
|
* See https://github.com/finos/legend-studio/issues/65
|
|
73
79
|
*/
|
|
74
|
-
const generateExecutionNodeLabel = (type: ExecutionNode): string => {
|
|
80
|
+
export const generateExecutionNodeLabel = (type: ExecutionNode): string => {
|
|
75
81
|
if (type instanceof SQLExecutionNode) {
|
|
76
82
|
return `SQL Execution Node`;
|
|
77
83
|
} else if (type instanceof RelationalTDSInstantiationExecutionNode) {
|
|
78
84
|
return `Relational TDS Instantiation Execution Node`;
|
|
85
|
+
} else if (type instanceof FunctionParametersValidationNode) {
|
|
86
|
+
return `Function Parameters Validation Node`;
|
|
87
|
+
} else if (type instanceof AllocationExecutionNode) {
|
|
88
|
+
return `Allocation Execution Node (${type.varName})`;
|
|
89
|
+
} else if (type instanceof ConstantExecutionNode) {
|
|
90
|
+
return `Constant Execution Node`;
|
|
91
|
+
} else if (type instanceof SequenceExecutionNode) {
|
|
92
|
+
return `Sequence Execution Node`;
|
|
79
93
|
} else {
|
|
80
94
|
return 'Other';
|
|
81
95
|
}
|
|
82
96
|
};
|
|
83
97
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
addUniqueEntry(childrenIds, childExecutionNode._UUID);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
executionNodeTreeNode.childrenIds = childrenIds;
|
|
108
|
-
|
|
109
|
-
return executionNodeTreeNode;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const generateExecutionPlanTreeNodeData = (
|
|
113
|
-
executionPlan: ExecutionPlan,
|
|
114
|
-
): ExecutionPlanViewTreeNodeData => {
|
|
115
|
-
const executionPlanNode = new ExecutionPlanViewTreeNodeData(
|
|
116
|
-
`Execution Plan`,
|
|
117
|
-
`Execution Plan`,
|
|
118
|
-
executionPlan,
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const childrenIds: string[] = [];
|
|
122
|
-
|
|
123
|
-
const rootNodeId = executionPlan.rootExecutionNode._UUID;
|
|
124
|
-
addUniqueEntry(childrenIds, rootNodeId);
|
|
125
|
-
executionPlanNode.childrenIds = childrenIds;
|
|
126
|
-
return executionPlanNode;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const getExecutionPlanTreeData = (
|
|
130
|
-
executionPlan: ExecutionPlan,
|
|
131
|
-
): TreeData<ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData> => {
|
|
132
|
-
const rootIds: string[] = [];
|
|
133
|
-
const nodes = new Map<
|
|
134
|
-
string,
|
|
135
|
-
ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData
|
|
136
|
-
>();
|
|
137
|
-
const executionPlanTreeNode =
|
|
138
|
-
generateExecutionPlanTreeNodeData(executionPlan);
|
|
139
|
-
addUniqueEntry(rootIds, executionPlanTreeNode.id);
|
|
140
|
-
nodes.set(executionPlanTreeNode.id, executionPlanTreeNode);
|
|
141
|
-
return { rootIds, nodes };
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const ExecutionNodeElementTreeNodeContainer: React.FC<
|
|
145
|
-
TreeNodeContainerProps<
|
|
146
|
-
ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
147
|
-
{
|
|
148
|
-
onNodeExpand: (
|
|
149
|
-
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
150
|
-
) => void;
|
|
151
|
-
}
|
|
152
|
-
>
|
|
153
|
-
> = (props) => {
|
|
154
|
-
const { node, level, stepPaddingInRem, onNodeSelect, innerProps } = props;
|
|
155
|
-
const { onNodeExpand } = innerProps;
|
|
156
|
-
const isExpandable = Boolean(node.childrenIds?.length);
|
|
157
|
-
const selectNode = (): void => onNodeSelect?.(node);
|
|
158
|
-
const expandNode = (): void => onNodeExpand(node);
|
|
159
|
-
const nodeExpandIcon = isExpandable ? (
|
|
160
|
-
node.isOpen ? (
|
|
161
|
-
<ChevronDownIcon />
|
|
98
|
+
const ExecutionNodeElementTreeNodeContainer = observer(
|
|
99
|
+
(
|
|
100
|
+
props: TreeNodeContainerProps<
|
|
101
|
+
ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
102
|
+
{
|
|
103
|
+
onNodeExpand: (
|
|
104
|
+
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
105
|
+
) => void;
|
|
106
|
+
}
|
|
107
|
+
>,
|
|
108
|
+
) => {
|
|
109
|
+
const { node, level, stepPaddingInRem, onNodeSelect } = props;
|
|
110
|
+
const isExpandable = Boolean(node.childrenIds?.length);
|
|
111
|
+
const selectNode = (): void => onNodeSelect?.(node);
|
|
112
|
+
const nodeExpandIcon = isExpandable ? (
|
|
113
|
+
node.isOpen ? (
|
|
114
|
+
<ChevronDownIcon />
|
|
115
|
+
) : (
|
|
116
|
+
<ChevronRightIcon />
|
|
117
|
+
)
|
|
162
118
|
) : (
|
|
163
|
-
<
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
onClick={selectNode}
|
|
185
|
-
>
|
|
186
|
-
<div className="tree-view__node__icon">
|
|
187
|
-
<div className="tree-view__node__expand-icon" onClick={expandNode}>
|
|
188
|
-
{nodeExpandIcon}
|
|
119
|
+
<div />
|
|
120
|
+
);
|
|
121
|
+
return (
|
|
122
|
+
<div
|
|
123
|
+
className={clsx(
|
|
124
|
+
'tree-view__node__container execution-plan-viewer__explorer-tree__node__container',
|
|
125
|
+
{
|
|
126
|
+
'menu__trigger--on-menu-open': !node.isSelected,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
'execution-plan-viewer__explorer-tree__node__container--selected':
|
|
130
|
+
node.isSelected,
|
|
131
|
+
},
|
|
132
|
+
)}
|
|
133
|
+
style={{
|
|
134
|
+
paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1)}rem`,
|
|
135
|
+
}}
|
|
136
|
+
onClick={selectNode}
|
|
137
|
+
>
|
|
138
|
+
<div className="tree-view__node__icon">
|
|
139
|
+
<div className="tree-view__node__expand-icon">{nodeExpandIcon}</div>
|
|
189
140
|
</div>
|
|
141
|
+
<button
|
|
142
|
+
className="tree-view__node__label execution-plan-viewer__explorer-tree__node__label"
|
|
143
|
+
tabIndex={-1}
|
|
144
|
+
title={node.id}
|
|
145
|
+
>
|
|
146
|
+
{node.label}
|
|
147
|
+
</button>
|
|
190
148
|
</div>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
title={node.id}
|
|
195
|
-
>
|
|
196
|
-
{node.label}
|
|
197
|
-
</button>
|
|
198
|
-
</div>
|
|
199
|
-
);
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
export const ExecutionPlanTree: React.FC<{
|
|
203
|
-
executionPlanState: ExecutionPlanState;
|
|
204
|
-
executionPlan: ExecutionPlan;
|
|
205
|
-
}> = (props) => {
|
|
206
|
-
const { executionPlanState, executionPlan } = props;
|
|
207
|
-
// NOTE: We only need to compute this once so we use lazy initial state syntax
|
|
208
|
-
// See https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
|
|
209
|
-
const [treeData, setTreeData] = useState<
|
|
210
|
-
TreeData<ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData>
|
|
211
|
-
>(() => getExecutionPlanTreeData(executionPlan));
|
|
212
|
-
const onNodeSelect = (
|
|
213
|
-
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
214
|
-
): void => {
|
|
215
|
-
if (node instanceof ExecutionPlanViewTreeNodeData) {
|
|
216
|
-
executionPlanState.transformMetadataToProtocolJson(node.executionPlan);
|
|
217
|
-
} else if (node instanceof ExecutionNodeTreeNodeData) {
|
|
218
|
-
executionPlanState.transformMetadataToProtocolJson(node.executionNode);
|
|
219
|
-
}
|
|
220
|
-
executionPlanState.setSelectedNode(node);
|
|
221
|
-
};
|
|
149
|
+
);
|
|
150
|
+
},
|
|
151
|
+
);
|
|
222
152
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const rootNode = node.executionPlan.rootExecutionNode;
|
|
230
|
-
const rootNodeTreeNode = generateExecutionNodeTreeNodeData(
|
|
231
|
-
rootNode,
|
|
232
|
-
generateExecutionNodeLabel(rootNode),
|
|
233
|
-
node,
|
|
234
|
-
);
|
|
235
|
-
treeData.nodes.set(rootNodeTreeNode.id, rootNodeTreeNode);
|
|
236
|
-
} else if (node instanceof ExecutionNodeTreeNodeData) {
|
|
237
|
-
if (node.executionNode.executionNodes.length > 0) {
|
|
238
|
-
node.executionNode.executionNodes.forEach((exen) => {
|
|
239
|
-
const executionNodeTreeNode = generateExecutionNodeTreeNodeData(
|
|
240
|
-
exen,
|
|
241
|
-
generateExecutionNodeLabel(exen),
|
|
242
|
-
node,
|
|
243
|
-
);
|
|
153
|
+
export const ExecutionPlanTree = observer(
|
|
154
|
+
(props: {
|
|
155
|
+
executionPlanState: ExecutionPlanState;
|
|
156
|
+
executionPlan: ExecutionPlan;
|
|
157
|
+
}) => {
|
|
158
|
+
const { executionPlanState } = props;
|
|
244
159
|
|
|
245
|
-
|
|
246
|
-
|
|
160
|
+
const onNodeExpand = (
|
|
161
|
+
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
162
|
+
): void => {
|
|
163
|
+
if (node.childrenIds?.length) {
|
|
164
|
+
node.setIsOpen(!node.isOpen);
|
|
165
|
+
if (node instanceof ExecutionPlanViewTreeNodeData) {
|
|
166
|
+
const rootNode = node.executionPlan.rootExecutionNode;
|
|
167
|
+
const rootNodeTreeNode = generateExecutionNodeTreeNodeData(
|
|
168
|
+
rootNode,
|
|
169
|
+
generateExecutionNodeLabel(rootNode),
|
|
170
|
+
node,
|
|
171
|
+
);
|
|
172
|
+
executionPlanState.setTreeNode(rootNodeTreeNode.id, rootNodeTreeNode);
|
|
173
|
+
} else if (node instanceof ExecutionNodeTreeNodeData) {
|
|
174
|
+
if (node.executionNode.executionNodes.length > 0) {
|
|
175
|
+
node.executionNode.executionNodes.forEach((exen) => {
|
|
176
|
+
const executionNodeTreeNode = generateExecutionNodeTreeNodeData(
|
|
177
|
+
exen,
|
|
178
|
+
generateExecutionNodeLabel(exen),
|
|
179
|
+
node,
|
|
180
|
+
);
|
|
181
|
+
executionPlanState.setTreeNode(
|
|
182
|
+
executionNodeTreeNode.id,
|
|
183
|
+
executionNodeTreeNode,
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
247
187
|
}
|
|
248
188
|
}
|
|
249
|
-
}
|
|
250
189
|
|
|
251
|
-
|
|
252
|
-
|
|
190
|
+
executionPlanState.refreshTreeData();
|
|
191
|
+
};
|
|
253
192
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
.
|
|
193
|
+
const onNodeSelect = (
|
|
194
|
+
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
195
|
+
): void => {
|
|
196
|
+
if (node instanceof ExecutionPlanViewTreeNodeData) {
|
|
197
|
+
executionPlanState.transformMetadataToProtocolJson(node.executionPlan);
|
|
198
|
+
} else if (node instanceof ExecutionNodeTreeNodeData) {
|
|
199
|
+
executionPlanState.transformMetadataToProtocolJson(node.executionNode);
|
|
200
|
+
}
|
|
201
|
+
if (!(node.isOpen === true && node.isSelected === false)) {
|
|
202
|
+
onNodeExpand(node);
|
|
203
|
+
}
|
|
204
|
+
executionPlanState.setSelectedNode(node);
|
|
205
|
+
};
|
|
263
206
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
207
|
+
const getChildNodes = (
|
|
208
|
+
node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
|
|
209
|
+
): (ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData)[] => {
|
|
210
|
+
if (!node.childrenIds || node.childrenIds.length === 0) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
const childrenNodes = node.childrenIds
|
|
214
|
+
.map((id) => executionPlanState.nonNullableTreeData.nodes.get(id))
|
|
215
|
+
.filter(isNonNullable);
|
|
216
|
+
return childrenNodes;
|
|
217
|
+
};
|
|
218
|
+
return (
|
|
219
|
+
<TreeView
|
|
220
|
+
components={{
|
|
221
|
+
TreeNodeContainer: ExecutionNodeElementTreeNodeContainer,
|
|
222
|
+
}}
|
|
223
|
+
treeData={executionPlanState.nonNullableTreeData}
|
|
224
|
+
getChildNodes={getChildNodes}
|
|
225
|
+
onNodeSelect={onNodeSelect}
|
|
226
|
+
innerProps={{
|
|
227
|
+
onNodeExpand,
|
|
228
|
+
}}
|
|
229
|
+
/>
|
|
230
|
+
);
|
|
231
|
+
},
|
|
232
|
+
);
|
|
280
233
|
|
|
281
234
|
const ExecutionNodeViewer = observer(
|
|
282
235
|
(props: {
|
|
@@ -289,6 +242,50 @@ const ExecutionNodeViewer = observer(
|
|
|
289
242
|
<SQLExecutionNodeViewer
|
|
290
243
|
query={executionNode.sqlQuery}
|
|
291
244
|
resultColumns={executionNode.resultColumns}
|
|
245
|
+
resultType={executionNode.resultType}
|
|
246
|
+
executionPlanState={executionPlanState}
|
|
247
|
+
viewJson={true}
|
|
248
|
+
/>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
if (executionNode instanceof RelationalTDSInstantiationExecutionNode) {
|
|
252
|
+
return (
|
|
253
|
+
<RelationalTDSInstantiationExecutionNodeViewer
|
|
254
|
+
node={executionNode}
|
|
255
|
+
executionPlanState={executionPlanState}
|
|
256
|
+
/>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (executionNode instanceof FunctionParametersValidationNode) {
|
|
260
|
+
return (
|
|
261
|
+
<FunctionParametersValidationNodeViewer
|
|
262
|
+
functionParameters={executionNode.functionParameters}
|
|
263
|
+
parameterValidationContext={executionNode.parameterValidationContext}
|
|
264
|
+
executionPlanState={executionPlanState}
|
|
265
|
+
resultType={executionNode.resultType}
|
|
266
|
+
/>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
if (executionNode instanceof AllocationExecutionNode) {
|
|
270
|
+
return (
|
|
271
|
+
<AllocationExecutionNodeViewer
|
|
272
|
+
node={executionNode}
|
|
273
|
+
executionPlanState={executionPlanState}
|
|
274
|
+
/>
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
if (executionNode instanceof ConstantExecutionNode) {
|
|
278
|
+
return (
|
|
279
|
+
<ConstantExecutionNodeViewer
|
|
280
|
+
cnode={executionNode}
|
|
281
|
+
executionPlanState={executionPlanState}
|
|
282
|
+
/>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
if (executionNode instanceof SequenceExecutionNode) {
|
|
286
|
+
return (
|
|
287
|
+
<SequenceExecutionNodeViewer
|
|
288
|
+
node={executionNode}
|
|
292
289
|
executionPlanState={executionPlanState}
|
|
293
290
|
/>
|
|
294
291
|
);
|
|
@@ -328,6 +325,19 @@ const ExecutionPlanViewPanel = observer(
|
|
|
328
325
|
currentElement = executionPlanState.selectedNode.executionNode;
|
|
329
326
|
}
|
|
330
327
|
}
|
|
328
|
+
|
|
329
|
+
useEffect(() => {
|
|
330
|
+
if (executionPlanState.selectedNode === undefined) {
|
|
331
|
+
const firstNode =
|
|
332
|
+
executionPlanState.treeData?.nodes.get(EXECUTION_PLAN);
|
|
333
|
+
if (firstNode instanceof ExecutionPlanViewTreeNodeData) {
|
|
334
|
+
executionPlanState.transformMetadataToProtocolJson(
|
|
335
|
+
firstNode.executionPlan,
|
|
336
|
+
);
|
|
337
|
+
executionPlanState.setSelectedNode(firstNode);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}, [executionPlanState]);
|
|
331
341
|
const nativeViewModes = Object.values(EXECUTION_PLAN_VIEW_MODE);
|
|
332
342
|
|
|
333
343
|
return (
|
|
@@ -485,7 +495,7 @@ export const ExecutionPlanViewer = observer(
|
|
|
485
495
|
const { executionPlanState } = props;
|
|
486
496
|
const closePlanViewer = (): void => {
|
|
487
497
|
executionPlanState.setRawPlan(undefined);
|
|
488
|
-
executionPlanState.
|
|
498
|
+
executionPlanState.initialize(undefined);
|
|
489
499
|
executionPlanState.setExecutionPlanDisplayData('');
|
|
490
500
|
executionPlanState.setSelectedNode(undefined);
|
|
491
501
|
executionPlanState.setDebugText(undefined);
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { observer } from 'mobx-react-lite';
|
|
18
|
+
import React from 'react';
|
|
19
|
+
import {
|
|
20
|
+
type ExecutionPlanState,
|
|
21
|
+
EXECUTION_PLAN_VIEW_MODE,
|
|
22
|
+
} from '../../stores/execution-plan/ExecutionPlanState.js';
|
|
23
|
+
import {
|
|
24
|
+
type VariableExpression,
|
|
25
|
+
type ParameterValidationContext,
|
|
26
|
+
Multiplicity,
|
|
27
|
+
type ResultType,
|
|
28
|
+
} from '@finos/legend-graph';
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
PanelListItem,
|
|
32
|
+
PanelDivider,
|
|
33
|
+
Button,
|
|
34
|
+
PanelContent,
|
|
35
|
+
} from '@finos/legend-art';
|
|
36
|
+
import { ResultTypeViewer } from './ResultTypeViewer.js';
|
|
37
|
+
|
|
38
|
+
export const FunctionParametersValidationNodeViewer: React.FC<{
|
|
39
|
+
functionParameters: VariableExpression[];
|
|
40
|
+
parameterValidationContext: ParameterValidationContext[];
|
|
41
|
+
resultType: ResultType;
|
|
42
|
+
executionPlanState: ExecutionPlanState;
|
|
43
|
+
}> = observer((props) => {
|
|
44
|
+
const { functionParameters, resultType, executionPlanState } = props;
|
|
45
|
+
const applicationStore = executionPlanState.applicationStore;
|
|
46
|
+
|
|
47
|
+
const showMultiplicity = (multiplicity: Multiplicity): string => {
|
|
48
|
+
if (multiplicity === Multiplicity.ZERO) {
|
|
49
|
+
return '[0]';
|
|
50
|
+
}
|
|
51
|
+
if (multiplicity === Multiplicity.ONE) {
|
|
52
|
+
return '[1]';
|
|
53
|
+
}
|
|
54
|
+
if (multiplicity === Multiplicity.ZERO_ONE) {
|
|
55
|
+
return '[0..1]';
|
|
56
|
+
}
|
|
57
|
+
if (
|
|
58
|
+
multiplicity === Multiplicity.ZERO_MANY ||
|
|
59
|
+
multiplicity === Multiplicity.ONE_MANY
|
|
60
|
+
) {
|
|
61
|
+
return '[*]';
|
|
62
|
+
}
|
|
63
|
+
if (multiplicity.upperBound === undefined) {
|
|
64
|
+
return `[${multiplicity.lowerBound.toString()}.. *]`;
|
|
65
|
+
}
|
|
66
|
+
return `[${multiplicity.lowerBound.toString()}..${multiplicity.upperBound.toString()}]`;
|
|
67
|
+
};
|
|
68
|
+
return (
|
|
69
|
+
<PanelContent
|
|
70
|
+
darkMode={
|
|
71
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
|
72
|
+
}
|
|
73
|
+
>
|
|
74
|
+
<div className="query-builder__function-parameters-validation__container">
|
|
75
|
+
<div>
|
|
76
|
+
<PanelListItem className="query-builder__function-parameters-validation__container__item__label">
|
|
77
|
+
Variables Details
|
|
78
|
+
</PanelListItem>
|
|
79
|
+
<PanelDivider />
|
|
80
|
+
<table className="table query-builder__function-parameters-validation__container__table">
|
|
81
|
+
<thead>
|
|
82
|
+
<tr>
|
|
83
|
+
<th className="table__cell--left">Name</th>
|
|
84
|
+
<th className="table__cell--left">Type</th>
|
|
85
|
+
</tr>
|
|
86
|
+
</thead>
|
|
87
|
+
<tbody>
|
|
88
|
+
{functionParameters.map((parameter) => (
|
|
89
|
+
<React.Fragment key={parameter.name}>
|
|
90
|
+
<tr>
|
|
91
|
+
<td className="table__cell--left">{parameter.name}</td>
|
|
92
|
+
<td className="table__cell--left">
|
|
93
|
+
{`${
|
|
94
|
+
parameter.genericType?.value.rawType.name
|
|
95
|
+
} ${showMultiplicity(parameter.multiplicity)}`}
|
|
96
|
+
</td>
|
|
97
|
+
</tr>
|
|
98
|
+
</React.Fragment>
|
|
99
|
+
))}
|
|
100
|
+
</tbody>
|
|
101
|
+
</table>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<PanelDivider />
|
|
105
|
+
<ResultTypeViewer resultType={resultType} />
|
|
106
|
+
<div className="query-builder__function-parameters-validation__container">
|
|
107
|
+
<Button
|
|
108
|
+
className="btn--dark execution-node-viewer__unsupported-view__to-text-mode__btn"
|
|
109
|
+
onClick={(): void =>
|
|
110
|
+
executionPlanState.setViewMode(EXECUTION_PLAN_VIEW_MODE.JSON)
|
|
111
|
+
}
|
|
112
|
+
text="View JSON"
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
<PanelDivider />
|
|
116
|
+
</PanelContent>
|
|
117
|
+
);
|
|
118
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { observer } from 'mobx-react-lite';
|
|
18
|
+
import {
|
|
19
|
+
type ExecutionPlanState,
|
|
20
|
+
EXECUTION_PLAN_VIEW_MODE,
|
|
21
|
+
} from '../../stores/execution-plan/ExecutionPlanState.js';
|
|
22
|
+
import {
|
|
23
|
+
SQLExecutionNode,
|
|
24
|
+
type RelationalTDSInstantiationExecutionNode,
|
|
25
|
+
} from '@finos/legend-graph';
|
|
26
|
+
import { PanelDivider, Button, PanelContent } from '@finos/legend-art';
|
|
27
|
+
import { SQLExecutionNodeViewerHelper } from './SQLExecutionNodeViewer.js';
|
|
28
|
+
import { ResultTypeViewer } from './ResultTypeViewer.js';
|
|
29
|
+
|
|
30
|
+
export const RelationalTDSInstantiationExecutionNodeViewer: React.FC<{
|
|
31
|
+
node: RelationalTDSInstantiationExecutionNode;
|
|
32
|
+
executionPlanState: ExecutionPlanState;
|
|
33
|
+
}> = observer((props) => {
|
|
34
|
+
const { node, executionPlanState } = props;
|
|
35
|
+
const resultType = node.resultType;
|
|
36
|
+
const applicationStore = executionPlanState.applicationStore;
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<PanelContent
|
|
40
|
+
darkMode={
|
|
41
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
{node.executionNodes.length > 0 &&
|
|
45
|
+
node.executionNodes[0] !== undefined &&
|
|
46
|
+
node.executionNodes[0] instanceof SQLExecutionNode && (
|
|
47
|
+
<SQLExecutionNodeViewerHelper
|
|
48
|
+
query={node.executionNodes[0].sqlQuery}
|
|
49
|
+
resultColumns={node.executionNodes[0].resultColumns}
|
|
50
|
+
resultType={node.executionNodes[0].resultType}
|
|
51
|
+
executionPlanState={executionPlanState}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
<PanelDivider />
|
|
55
|
+
<ResultTypeViewer resultType={resultType} />
|
|
56
|
+
<div className="query-builder__sql__container">
|
|
57
|
+
<Button
|
|
58
|
+
className="btn--dark execution-node-viewer__unsupported-view__to-text-mode__btn"
|
|
59
|
+
onClick={(): void =>
|
|
60
|
+
executionPlanState.setViewMode(EXECUTION_PLAN_VIEW_MODE.JSON)
|
|
61
|
+
}
|
|
62
|
+
text="View JSON"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
<PanelDivider />
|
|
66
|
+
</PanelContent>
|
|
67
|
+
);
|
|
68
|
+
});
|