Skip to content

Commit 3bb85e4

Browse files
authored
feat(cubesql): Redesign member pushdown to support more advanced join… (#6122)
* Redesign member pushdown to support more advanced join pushdown use cases * Run SQL API tests using release build to speed it up * Revert back unoptimized as it's faster * Increase timeout due to generalized member pushdown is a little bit slower * Fix warnings and revert back modified tests * Flatten empty filters * Fixes for join pushdown rules
1 parent 04ac787 commit 3bb85e4

File tree

14 files changed

+1854
-790
lines changed

14 files changed

+1854
-790
lines changed

.github/workflows/rust-cubesql.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949

5050
unit:
5151
runs-on: ubuntu-20.04
52-
timeout-minutes: 40
52+
timeout-minutes: 50
5353
name: Unit (Rewrite Engine)
5454

5555
steps:
@@ -80,7 +80,7 @@ jobs:
8080
CUBESQL_TESTING_CUBE_TOKEN: ${{ secrets.CUBESQL_TESTING_CUBE_TOKEN }}
8181
CUBESQL_TESTING_CUBE_URL: ${{ secrets.CUBESQL_TESTING_CUBE_URL }}
8282
CUBESQL_REWRITE_ENGINE: true
83-
CUBESQL_REWRITE_TIMEOUT: 30
83+
CUBESQL_REWRITE_TIMEOUT: 60
8484
run: cd rust/cubesql && cargo tarpaulin --workspace --no-fail-fast --avoid-cfg-tarpaulin --out Xml
8585
- name: Upload code coverage
8686
uses: codecov/codecov-action@v3
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "egraph-debug",
3+
"version": "0.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"react": "18.1.0",
7+
"react-dom": "18.1.0",
8+
"@antv/g6": "4.8.3"
9+
},
10+
"scripts": {
11+
"start": "GENERATE_SOURCEMAP=false && react-scripts start",
12+
"build": "react-scripts build",
13+
"test": "react-scripts test --env=jsdom",
14+
"eject": "react-scripts eject"
15+
},
16+
"devDependencies": {
17+
"react-scripts": "latest"
18+
},
19+
"browserslist": {
20+
"production": [
21+
">0.2%",
22+
"not dead",
23+
"not op_mini all"
24+
],
25+
"development": [
26+
"last 1 chrome version",
27+
"last 1 firefox version",
28+
"last 1 safari version"
29+
]
30+
}
31+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div id="container">
2+
<div id="ui"></div>
3+
</div>
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import G6 from '@antv/g6';
2+
import ReactDOM from 'react-dom';
3+
import React, { useState } from 'react';
4+
import { createRoot } from 'react-dom/client';
5+
import { iterations } from './iterations';
6+
7+
const data = { nodes: iterations[0].nodes, edges: iterations[0].edges, combos: iterations[0].combos };
8+
9+
const prevIter = (iteration, setIteration) => {
10+
if (iteration === 0) {
11+
return;
12+
}
13+
const toRemove = iterations[iteration];
14+
(toRemove.edges || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
15+
(toRemove.nodes || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
16+
(toRemove.combos || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
17+
(toRemove.removedCombos || []).forEach((n) => graph.addItem('combo', { ...n }));
18+
(toRemove.removedNodes || []).forEach((n) => {
19+
graph.addItem('node', { ...n, size: sizeByNode(n) });
20+
});
21+
(toRemove.removedEdges || []).forEach((n) => graph.addItem('edge', { ...n }));
22+
setIteration(iteration - 1);
23+
iteration -= 1;
24+
const toHighlight = iterations[iteration];
25+
(toHighlight.nodes || []).forEach((n) => graph.setItemState(graph.findById(n.id), 'justAdded', true));
26+
setTimeout(() => {
27+
graph.updateLayout();
28+
}, 1000);
29+
};
30+
31+
const sizeByNode = (n) => [60 + n.label.length * 5, 30];
32+
33+
data.nodes.forEach(n => n.size = sizeByNode(n));
34+
35+
const nextIter = (iteration, setIteration) => {
36+
if (iteration === iterations.length - 1) {
37+
return;
38+
}
39+
const nodes = graph.getNodes();
40+
nodes.forEach((node) => graph.setItemState(node, 'justAdded', false));
41+
setIteration(iteration + 1);
42+
iteration += 1;
43+
const toAdd = iterations[iteration];
44+
(toAdd.removedEdges || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
45+
(toAdd.removedNodes || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
46+
(toAdd.removedCombos || []).forEach((n) => graph.removeItem(graph.findById(n.id)));
47+
(toAdd.combos || []).forEach((n) => graph.addItem('combo', { ...n }));
48+
(toAdd.nodes || []).forEach((n) => {
49+
graph.addItem('node', { ...n, size: sizeByNode(n) });
50+
graph.setItemState(graph.findById(n.id), 'justAdded', true);
51+
});
52+
(toAdd.edges || []).forEach((n) => graph.addItem('edge', { ...n }));
53+
54+
setTimeout(() => {
55+
graph.updateLayout();
56+
}, 1000);
57+
};
58+
59+
const navigateToClass = (classId) => {
60+
if(!classId) {
61+
return;
62+
}
63+
graph.focusItem(graph.findById(classId + ''), true, {
64+
easing: 'easeCubic',
65+
duration: 500,
66+
});
67+
};
68+
69+
const UI = () => {
70+
const [iteration, setIteration] = useState(0);
71+
const [navigateTo, setNavigateTo] = useState('');
72+
const [navHistory, setNavHistory] = useState([]);
73+
return (<div>
74+
<div>
75+
<button onClick={() => prevIter(iteration, setIteration)}>Prev Iter</button>
76+
<button onClick={() => nextIter(iteration, setIteration)}>Next Iter</button>
77+
<span style={{ paddingLeft: 4, paddingRight: 4 }}>Iteration #{iteration + 1} / {iterations.length}</span>
78+
<input placeholder="Search Class ID" onChange={(e) => setNavigateTo(e.target.value)} value={navigateTo}></input>
79+
<button onClick={() => {
80+
navigateToClass(parseInt(navigateTo));
81+
if (!navHistory.includes(navigateTo)) {
82+
setNavHistory(navHistory.concat(navigateTo));
83+
}
84+
}}>
85+
Navigate
86+
</button>
87+
{
88+
navHistory.map(item => (
89+
<span style={{ paddingLeft: 4 }} key={item}>
90+
<button onClick={() => navigateToClass(parseInt(item))}>{item}</button>
91+
<button onClick={() => setNavHistory(navHistory.filter(i => i !== item))}>X</button>
92+
</span>
93+
))
94+
}
95+
</div>
96+
<div>
97+
<span>{iterations[iteration].appliedRules.join(', ')}</span>
98+
</div>
99+
</div>)
100+
}
101+
102+
const rootElement = document.getElementById('ui');
103+
const root = createRoot(rootElement);
104+
root.render(<UI />);
105+
106+
let fixSelectedItems = {
107+
fixAll: true,
108+
fixState: 'yourStateName', // 'selected' by default
109+
};
110+
111+
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
112+
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
113+
const width = (vw || container.scrollWidth) - 20;
114+
const height = (vh || container.scrollHeight || 500) - 30;
115+
const graph = new G6.Graph({
116+
container: 'container',
117+
width,
118+
height: height - 50,
119+
fitView: true,
120+
fitViewPadding: 30,
121+
animate: true,
122+
groupByTypes: false,
123+
modes: {
124+
125+
default: [
126+
'drag-combo',
127+
// 'drag-node',
128+
'drag-canvas',
129+
{
130+
type: 'zoom-canvas',
131+
fixSelectedItems,
132+
},
133+
{
134+
type: 'collapse-expand-combo',
135+
relayout: false,
136+
},
137+
'activate-relations'
138+
],
139+
},
140+
layout: {
141+
type: 'dagre',
142+
sortByCombo: true,
143+
ranksep: 20,
144+
nodesep: 10,
145+
},
146+
nodeStateStyles: {
147+
justAdded: {
148+
fill: '#c3e3ff',
149+
stroke: '#aaa',
150+
},
151+
},
152+
defaultNode: {
153+
size: [60, 30],
154+
type: 'rect',
155+
anchorPoints: [[0.5, 0], [0.5, 1]],
156+
style: {
157+
fill: '#FDE1CE',
158+
stroke: '#aaa',
159+
},
160+
},
161+
defaultEdge: {
162+
type: 'line',
163+
},
164+
defaultCombo: {
165+
type: 'rect',
166+
style: {
167+
fillOpacity: 0.1,
168+
fill: '#C4E3B2',
169+
stroke: '#C4E3B2',
170+
},
171+
},
172+
});
173+
graph.data(data);
174+
graph.render();
175+
const nodes = graph.getNodes();
176+
nodes.forEach((node) => graph.setItemState(node, 'justAdded', true));
177+
178+
if (typeof window !== 'undefined')
179+
window.onresize = () => {
180+
if (!graph || graph.get('destroyed')) return;
181+
if (!container || !container.scrollWidth || !container.scrollHeight) return;
182+
graph.changeSize(container.scrollWidth, container.scrollHeight - 30);
183+
};
184+

0 commit comments

Comments
 (0)