Skip to content

Commit 36275d6

Browse files
committed
feat: Optimize and fix filtering on toStartOfX primary key expressions
1 parent 3332d5e commit 36275d6

File tree

10 files changed

+840
-27
lines changed

10 files changed

+840
-27
lines changed

.changeset/fluffy-mails-sparkle.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@hyperdx/common-utils": patch
3+
"@hyperdx/app": patch
4+
---
5+
6+
feat: Optimize and fix filtering on toStartOfX primary key expressions

packages/app/src/DBDashboardPage.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import OnboardingModal from './components/OnboardingModal';
6666
import { Tags } from './components/Tags';
6767
import useDashboardFilters from './hooks/useDashboardFilters';
6868
import { useDashboardRefresh } from './hooks/useDashboardRefresh';
69+
import { useOptimizedTimestampValueExpression } from './hooks/useOptimizedTimestampValueExpression';
6970
import { parseAsStringWithNewLines } from './utils/queryParsers';
7071
import api from './api';
7172
import { DEFAULT_CHART_CONFIG } from './ChartUtils';
@@ -158,6 +159,10 @@ const Tile = forwardRef(
158159
const { data: source } = useSource({
159160
id: chart.config.source,
160161
});
162+
const {
163+
timestampValueExpression: optimizedTimestampValueExpression,
164+
isLoading: isOptimizedTimestampExpressionLoading,
165+
} = useOptimizedTimestampValueExpression(chart.config.source);
161166

162167
// const prevSource = usePrevious(source);
163168
// const prevChart = usePrevious(chart);
@@ -166,7 +171,7 @@ const Tile = forwardRef(
166171
// const prevFilters = usePrevious(filters);
167172

168173
useEffect(() => {
169-
if (source != null) {
174+
if (source != null && !isOptimizedTimestampExpressionLoading) {
170175
// TODO: will need to update this when we allow for multiple metrics per chart
171176
const firstSelect = chart.config.select[0];
172177
const metricType =
@@ -178,7 +183,9 @@ const Tile = forwardRef(
178183
connection: source.connection,
179184
dateRange,
180185
granularity,
181-
timestampValueExpression: source.timestampValueExpression,
186+
timestampValueExpression:
187+
optimizedTimestampValueExpression ||
188+
source.timestampValueExpression,
182189
from: {
183190
databaseName: source.from?.databaseName || 'default',
184191
tableName: tableName || '',
@@ -189,7 +196,15 @@ const Tile = forwardRef(
189196
});
190197
}
191198
}
192-
}, [source, chart, dateRange, granularity, filters]);
199+
}, [
200+
source,
201+
chart,
202+
dateRange,
203+
granularity,
204+
filters,
205+
optimizedTimestampValueExpression,
206+
isOptimizedTimestampExpressionLoading,
207+
]);
193208

194209
const [hovered, setHovered] = useState(false);
195210

packages/app/src/DBSearchPage.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ import PatternTable from './components/PatternTable';
100100
import { DBSearchHeatmapChart } from './components/Search/DBSearchHeatmapChart';
101101
import SourceSchemaPreview from './components/SourceSchemaPreview';
102102
import { useTableMetadata } from './hooks/useMetadata';
103+
import { useOptimizedTimestampValueExpression } from './hooks/useOptimizedTimestampValueExpression';
103104
import { useSqlSuggestions } from './hooks/useSqlSuggestions';
104105
import {
105106
parseAsSortingStateString,
@@ -484,13 +485,19 @@ function useSearchedConfigToChartConfig({
484485
filters,
485486
orderBy,
486487
}: SearchConfig) {
487-
const { data: sourceObj, isLoading } = useSource({
488+
const { data: sourceObj, isLoading: isSourceLoading } = useSource({
488489
id: source,
489490
});
490491
const defaultOrderBy = useDefaultOrderBy(source);
492+
const {
493+
timestampValueExpression: optimizedTimestampValueExpression,
494+
isLoading: isTimestampValueExpressionLoading,
495+
} = useOptimizedTimestampValueExpression(source);
496+
497+
const isLoading = isSourceLoading || isTimestampValueExpressionLoading;
491498

492499
return useMemo(() => {
493-
if (sourceObj != null) {
500+
if (sourceObj != null && !isLoading) {
494501
return {
495502
data: {
496503
select: select || (sourceObj.defaultTableSelectExpression ?? ''),
@@ -509,7 +516,9 @@ function useSearchedConfigToChartConfig({
509516
...(filters != null ? { filters } : {}),
510517
where: where ?? '',
511518
whereLanguage: whereLanguage ?? 'sql',
512-
timestampValueExpression: sourceObj.timestampValueExpression,
519+
timestampValueExpression:
520+
optimizedTimestampValueExpression ||
521+
sourceObj.timestampValueExpression,
513522
implicitColumnExpression: sourceObj.implicitColumnExpression,
514523
connection: sourceObj.connection,
515524
displayType: DisplayType.Search,
@@ -527,6 +536,7 @@ function useSearchedConfigToChartConfig({
527536
where,
528537
whereLanguage,
529538
defaultOrderBy,
539+
optimizedTimestampValueExpression,
530540
]);
531541
}
532542

packages/app/src/components/DBEditTimeChartForm.tsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { TimePicker } from '@/components/TimePicker';
5757
import { IS_LOCAL_MODE } from '@/config';
5858
import { GranularityPickerControlled } from '@/GranularityPicker';
5959
import { useFetchMetricResourceAttrs } from '@/hooks/useFetchMetricResourceAttrs';
60+
import { useOptimizedTimestampValueExpression } from '@/hooks/useOptimizedTimestampValueExpression';
6061
import SearchInputV2 from '@/SearchInputV2';
6162
import { getFirstTimestampValueExpression, useSource } from '@/source';
6263
import { parseTimeQuery } from '@/timeQuery';
@@ -490,15 +491,22 @@ export default function EditTimeChartForm({
490491
ChartConfigWithDateRange | undefined
491492
>(undefined);
492493

494+
const {
495+
timestampValueExpression: optimizedTimestampValueExpression,
496+
isLoading: isLoadingOptimizedTimestampExpression,
497+
} = useOptimizedTimestampValueExpression(tableSource?.id);
498+
493499
const onSubmit = useCallback(() => {
494500
handleSubmit(form => {
495501
setChartConfig(form);
496-
if (tableSource != null) {
502+
if (tableSource != null && !isLoadingOptimizedTimestampExpression) {
497503
const isSelectEmpty = !form.select || form.select.length === 0; // select is string or array
498504
const newConfig = {
499505
...form,
500506
from: tableSource.from,
501-
timestampValueExpression: tableSource.timestampValueExpression,
507+
timestampValueExpression:
508+
optimizedTimestampValueExpression ||
509+
tableSource.timestampValueExpression,
502510
dateRange,
503511
connection: tableSource.connection,
504512
implicitColumnExpression: tableSource.implicitColumnExpression,
@@ -516,7 +524,15 @@ export default function EditTimeChartForm({
516524
);
517525
}
518526
})();
519-
}, [handleSubmit, setChartConfig, setQueriedConfig, tableSource, dateRange]);
527+
}, [
528+
handleSubmit,
529+
setChartConfig,
530+
setQueriedConfig,
531+
tableSource,
532+
dateRange,
533+
optimizedTimestampValueExpression,
534+
isLoadingOptimizedTimestampExpression,
535+
]);
520536

521537
useEffect(() => {
522538
if (submitRef) {
@@ -589,7 +605,9 @@ export default function EditTimeChartForm({
589605
},
590606
],
591607
dateRange,
592-
timestampValueExpression: tableSource.timestampValueExpression,
608+
timestampValueExpression:
609+
optimizedTimestampValueExpression ||
610+
tableSource.timestampValueExpression,
593611
connection: tableSource.connection,
594612
from: tableSource.from,
595613
limit: { limit: 200 },
@@ -600,7 +618,13 @@ export default function EditTimeChartForm({
600618
granularity: undefined,
601619
}
602620
: null,
603-
[queriedConfig, tableSource, dateRange, queryReady],
621+
[
622+
queriedConfig,
623+
tableSource,
624+
dateRange,
625+
queryReady,
626+
optimizedTimestampValueExpression,
627+
],
604628
);
605629

606630
// Need to force a rerender on change as the modal will not be mounted when initially rendered

0 commit comments

Comments
 (0)