You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by fj...@apache.org on 2019/06/07 15:32:15 UTC
[incubator-druid] branch master updated: Web console: prevent the
time parse view from going into a bad state (#7846)
This is an automated email from the ASF dual-hosted git repository.
fjy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push:
new df01335 Web console: prevent the time parse view from going into a bad state (#7846)
df01335 is described below
commit df01335789f6e4f89d70b7b33dc373b8afc99c2e
Author: Vadim Ogievetsky <va...@gmail.com>
AuthorDate: Fri Jun 7 08:32:10 2019 -0700
Web console: prevent the time parse view from going into a bad state (#7846)
* prevent the time parse view from going into a bad state
* add test
---
.../__snapshots__/table-cell.spec.tsx.snap | 8 +++
.../src/components/table-cell/table-cell.spec.tsx | 11 ++++
.../src/components/table-cell/table-cell.tsx | 6 ++-
web-console/src/utils/sampler.ts | 59 +++++++++++++++++++++-
4 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap
index 48d579d..d1cf2ff 100644
--- a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap
+++ b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap
@@ -43,6 +43,14 @@ exports[`table cell matches snapshot null 1`] = `
</span>
`;
+exports[`table cell matches snapshot null timestamp 1`] = `
+<span
+ class="table-cell unparseable"
+>
+ unparseable timestamp
+</span>
+`;
+
exports[`table cell matches snapshot simple 1`] = `Hello World`;
exports[`table cell matches snapshot truncate 1`] = `
diff --git a/web-console/src/components/table-cell/table-cell.spec.tsx b/web-console/src/components/table-cell/table-cell.spec.tsx
index 821119a..1401a74 100644
--- a/web-console/src/components/table-cell/table-cell.spec.tsx
+++ b/web-console/src/components/table-cell/table-cell.spec.tsx
@@ -33,6 +33,17 @@ describe('table cell', () => {
expect(container.firstChild).toMatchSnapshot();
});
+ it('matches snapshot null timestamp', () => {
+ const tableCell = <TableCell
+ value={null}
+ unparseable={false}
+ timestamp
+ />;
+
+ const { container } = render(tableCell);
+ expect(container.firstChild).toMatchSnapshot();
+ });
+
it('matches snapshot simple', () => {
const tableCell = <TableCell
value="Hello World"
diff --git a/web-console/src/components/table-cell/table-cell.tsx b/web-console/src/components/table-cell/table-cell.tsx
index 6970b1d..9801dfb 100644
--- a/web-console/src/components/table-cell/table-cell.tsx
+++ b/web-console/src/components/table-cell/table-cell.tsx
@@ -89,7 +89,11 @@ export class TableCell extends React.PureComponent<NullTableCellProps, {}> {
return TableCell.possiblyTruncate(String(value));
}
} else {
- return <span className="table-cell null">null</span>;
+ if (timestamp) {
+ return <span className="table-cell unparseable">unparseable timestamp</span>;
+ } else {
+ return <span className="table-cell null">null</span>;
+ }
}
}
}
diff --git a/web-console/src/utils/sampler.ts b/web-console/src/utils/sampler.ts
index 4a3f7fc..cff22b9 100644
--- a/web-console/src/utils/sampler.ts
+++ b/web-console/src/utils/sampler.ts
@@ -24,7 +24,7 @@ import {
DimensionsSpec,
getEmptyTimestampSpec, getSpecType,
IngestionSpec,
- IoConfig, MetricSpec,
+ IoConfig, isColumnTimestampSpec, MetricSpec,
Parser,
ParseSpec,
Transform, TransformSpec
@@ -209,7 +209,42 @@ export async function sampleForTimestamp(spec: IngestionSpec, sampleStrategy: Sa
const ioConfig: IoConfig = makeSamplerIoConfig(deepGet(spec, 'ioConfig'), samplerType, sampleStrategy);
const parser: Parser = deepGet(spec, 'dataSchema.parser') || {};
const parseSpec: ParseSpec = deepGet(spec, 'dataSchema.parser.parseSpec') || {};
+ const timestampSpec: ParseSpec = deepGet(spec, 'dataSchema.parser.parseSpec.timestampSpec') || getEmptyTimestampSpec();
+ const columnTimestampSpec = isColumnTimestampSpec(timestampSpec);
+ // First do a query with a static timestamp spec
+ const sampleSpecColumns: SampleSpec = {
+ type: samplerType,
+ spec: {
+ type: samplerType,
+ ioConfig: deepSet(ioConfig, 'type', samplerType),
+ dataSchema: {
+ dataSource: 'sample',
+ parser: {
+ type: parser.type,
+ parseSpec: (
+ parser.parseSpec ?
+ Object.assign({}, parseSpec, {
+ dimensionsSpec: {},
+ timestampSpec: columnTimestampSpec ? getEmptyTimestampSpec() : timestampSpec
+ }) :
+ undefined
+ ) as any
+ }
+ }
+ },
+ samplerConfig: Object.assign({}, BASE_SAMPLER_CONFIG, {
+ cacheKey
+ })
+ };
+
+ const sampleColumns = await postToSampler(sampleSpecColumns, 'timestamp-columns');
+
+ // If we are not parsing a column then there is nothing left to do
+ if (!columnTimestampSpec) return sampleColumns;
+
+ // If we are trying to parts a column then get a bit fancy:
+ // Query the same sample again (same cache key)
const sampleSpec: SampleSpec = {
type: samplerType,
spec: {
@@ -230,7 +265,27 @@ export async function sampleForTimestamp(spec: IngestionSpec, sampleStrategy: Sa
})
};
- return postToSampler(sampleSpec, 'timestamp');
+ const sampleTime = await postToSampler(sampleSpec, 'timestamp-time');
+
+ if (
+ sampleTime.cacheKey !== sampleColumns.cacheKey ||
+ sampleTime.data.length !== sampleColumns.data.length
+ ) {
+ // If the two responses did not come from the same cache (or for some reason have different lengths) then
+ // just return the one with the parsed time column.
+ return sampleTime;
+ }
+
+ const sampleTimeData = sampleTime.data;
+ return Object.assign({}, sampleColumns, {
+ data: sampleColumns.data.map((d, i) => {
+ // Merge the column sample with the time column sample
+ if (!d.parsed) return d;
+ const timeDatumParsed = sampleTimeData[i].parsed;
+ d.parsed.__time = timeDatumParsed ? timeDatumParsed.__time : null;
+ return d;
+ })
+ });
}
export async function sampleForTransform(spec: IngestionSpec, sampleStrategy: SampleStrategy, cacheKey: string | undefined): Promise<SampleResponse> {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org