mirror of https://github.com/apache/druid.git
add useConcurrentLocks toggle (#16899)
This commit is contained in:
parent
ca82ecd352
commit
8181ef627a
|
@ -40,6 +40,7 @@ export interface QueryContext {
|
|||
sqlJoinAlgorithm?: SqlJoinAlgorithm;
|
||||
failOnEmptyInsert?: boolean;
|
||||
waitUntilSegmentsLoad?: boolean;
|
||||
useConcurrentLocks?: boolean;
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -61,6 +62,7 @@ export const DEFAULT_SERVER_QUERY_CONTEXT: QueryContext = {
|
|||
sqlJoinAlgorithm: 'broadcast',
|
||||
failOnEmptyInsert: false,
|
||||
waitUntilSegmentsLoad: false,
|
||||
useConcurrentLocks: false,
|
||||
};
|
||||
|
||||
export interface QueryWithContext {
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`RunPanel matches snapshot on msq (auto) query 1`] = `
|
||||
<div
|
||||
class="run-panel"
|
||||
>
|
||||
<button
|
||||
class="bp5-button bp5-intent-primary"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="bp5-icon bp5-icon-caret-right"
|
||||
>
|
||||
<svg
|
||||
data-icon="caret-right"
|
||||
height="16"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
>
|
||||
<path
|
||||
d="M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="bp5-button-text"
|
||||
>
|
||||
Run
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="bp5-button-group"
|
||||
>
|
||||
<span
|
||||
class="bp5-popover-target"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
class="bp5-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="bp5-button-text"
|
||||
>
|
||||
Engine: sql-msq-task
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="bp5-icon bp5-icon-caret-down"
|
||||
>
|
||||
<svg
|
||||
data-icon="caret-down"
|
||||
height="16"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
>
|
||||
<path
|
||||
d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
<span
|
||||
class="max-tasks-button bp5-popover-target"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
class="bp5-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="bp5-button-text"
|
||||
>
|
||||
Max tasks: 9 (full cluster capacity)
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="bp5-icon bp5-icon-caret-down"
|
||||
>
|
||||
<svg
|
||||
data-icon="caret-down"
|
||||
height="16"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
>
|
||||
<path
|
||||
d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`RunPanel matches snapshot on native (auto) query 1`] = `
|
||||
<div
|
||||
class="run-panel"
|
||||
>
|
||||
<button
|
||||
class="bp5-button bp5-intent-primary"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="bp5-icon bp5-icon-caret-right"
|
||||
>
|
||||
<svg
|
||||
data-icon="caret-right"
|
||||
height="16"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
>
|
||||
<path
|
||||
d="M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="bp5-button-text"
|
||||
>
|
||||
Run
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="bp5-button-group"
|
||||
>
|
||||
<span
|
||||
class="bp5-popover-target"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
class="bp5-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="bp5-button-text"
|
||||
>
|
||||
Engine: auto (sql-native)
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="bp5-icon bp5-icon-caret-down"
|
||||
>
|
||||
<svg
|
||||
data-icon="caret-down"
|
||||
height="16"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
>
|
||||
<path
|
||||
d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { DEFAULT_SERVER_QUERY_CONTEXT, DRUID_ENGINES, WorkbenchQuery } from '../../../druid-models';
|
||||
|
||||
import { RunPanel } from './run-panel';
|
||||
|
||||
describe('RunPanel', () => {
|
||||
it('matches snapshot on native (auto) query', () => {
|
||||
const runPanel = (
|
||||
<RunPanel
|
||||
query={WorkbenchQuery.blank().changeQueryString(`SELECT * FROM wikipedia`)}
|
||||
onQueryChange={() => {}}
|
||||
running={false}
|
||||
onRun={() => {}}
|
||||
queryEngines={DRUID_ENGINES}
|
||||
clusterCapacity={9}
|
||||
defaultQueryContext={DEFAULT_SERVER_QUERY_CONTEXT}
|
||||
/>
|
||||
);
|
||||
const { container } = render(runPanel);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('matches snapshot on msq (auto) query', () => {
|
||||
const runPanel = (
|
||||
<RunPanel
|
||||
query={WorkbenchQuery.blank()
|
||||
.changeQueryString(`SELECT * FROM wikipedia`)
|
||||
.changeEngine('sql-msq-task')}
|
||||
onQueryChange={() => {}}
|
||||
running={false}
|
||||
onRun={() => {}}
|
||||
queryEngines={DRUID_ENGINES}
|
||||
clusterCapacity={9}
|
||||
defaultQueryContext={DEFAULT_SERVER_QUERY_CONTEXT}
|
||||
/>
|
||||
);
|
||||
const { container } = render(runPanel);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -103,7 +103,6 @@ export interface RunPanelProps
|
|||
query: WorkbenchQuery;
|
||||
onQueryChange(query: WorkbenchQuery): void;
|
||||
running: boolean;
|
||||
small?: boolean;
|
||||
onRun(preview: boolean): void | Promise<void>;
|
||||
queryEngines: DruidEngine[];
|
||||
clusterCapacity: number | undefined;
|
||||
|
@ -120,7 +119,6 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
onRun,
|
||||
moreMenu,
|
||||
running,
|
||||
small,
|
||||
queryEngines,
|
||||
clusterCapacity,
|
||||
defaultQueryContext,
|
||||
|
@ -166,6 +164,11 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
queryContext,
|
||||
defaultQueryContext,
|
||||
);
|
||||
const useConcurrentLocks = getQueryContextKey(
|
||||
'useConcurrentLocks',
|
||||
queryContext,
|
||||
defaultQueryContext,
|
||||
);
|
||||
const finalizeAggregations = queryContext.finalizeAggregations;
|
||||
const waitUntilSegmentsLoad = queryContext.waitUntilSegmentsLoad;
|
||||
const groupByEnableMultiValueUnnesting = queryContext.groupByEnableMultiValueUnnesting;
|
||||
|
@ -198,7 +201,6 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
}, [onRun]);
|
||||
|
||||
const hotkeys = useMemo(() => {
|
||||
if (small) return [];
|
||||
return [
|
||||
{
|
||||
allowInInput: true,
|
||||
|
@ -217,7 +219,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
onKeyDown: handlePreview,
|
||||
},
|
||||
];
|
||||
}, [small, handleRun, handlePreview]);
|
||||
}, [handleRun, handlePreview]);
|
||||
|
||||
useHotkeys(hotkeys);
|
||||
|
||||
|
@ -264,9 +266,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
icon={IconNames.CARET_RIGHT}
|
||||
onClick={() => void onRun(false)}
|
||||
text="Run"
|
||||
intent={!emptyQuery && !small ? Intent.PRIMARY : undefined}
|
||||
small={small}
|
||||
minimal={small}
|
||||
intent={!emptyQuery ? Intent.PRIMARY : undefined}
|
||||
/>
|
||||
{ingestMode && (
|
||||
<Button
|
||||
|
@ -274,11 +274,9 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
icon={IconNames.EYE_OPEN}
|
||||
onClick={() => void onRun(true)}
|
||||
text="Preview"
|
||||
small={small}
|
||||
minimal={small}
|
||||
/>
|
||||
)}
|
||||
{!small && onQueryChange && (
|
||||
{onQueryChange && (
|
||||
<ButtonGroup>
|
||||
<Popover
|
||||
position={Position.BOTTOM_LEFT}
|
||||
|
@ -366,6 +364,45 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
)}
|
||||
{effectiveEngine === 'sql-msq-task' ? (
|
||||
<>
|
||||
<MenuItem icon={IconNames.BRING_DATA} text="INSERT / REPLACE specific context">
|
||||
<MenuCheckbox
|
||||
checked={useConcurrentLocks}
|
||||
text="Use concurrent locks"
|
||||
onChange={() =>
|
||||
changeQueryContext({
|
||||
...queryContext,
|
||||
useConcurrentLocks: !useConcurrentLocks,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<MenuTristate
|
||||
icon={IconNames.DISABLE}
|
||||
text="Fail on empty insert"
|
||||
value={failOnEmptyInsert}
|
||||
undefinedEffectiveValue={false}
|
||||
onValueChange={failOnEmptyInsert =>
|
||||
changeQueryContext({ ...queryContext, failOnEmptyInsert })
|
||||
}
|
||||
/>
|
||||
<MenuTristate
|
||||
icon={IconNames.STOPWATCH}
|
||||
text="Wait until segments have loaded"
|
||||
value={waitUntilSegmentsLoad}
|
||||
undefinedEffectiveValue={ingestMode}
|
||||
onValueChange={waitUntilSegmentsLoad =>
|
||||
changeQueryContext({ ...queryContext, waitUntilSegmentsLoad })
|
||||
}
|
||||
/>
|
||||
<MenuItem
|
||||
icon={IconNames.TH_DERIVED}
|
||||
text="Edit index spec"
|
||||
label={summarizeIndexSpec(indexSpec)}
|
||||
shouldDismissPopover={false}
|
||||
onClick={() => {
|
||||
setIndexSpecDialogSpec(indexSpec || {});
|
||||
}}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={IconNames.ERROR}
|
||||
text="Max parse exceptions"
|
||||
|
@ -383,15 +420,6 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
/>
|
||||
))}
|
||||
</MenuItem>
|
||||
<MenuTristate
|
||||
icon={IconNames.DISABLE}
|
||||
text="Fail on empty insert"
|
||||
value={failOnEmptyInsert}
|
||||
undefinedEffectiveValue={false}
|
||||
onValueChange={failOnEmptyInsert =>
|
||||
changeQueryContext({ ...queryContext, failOnEmptyInsert })
|
||||
}
|
||||
/>
|
||||
<MenuTristate
|
||||
icon={IconNames.TRANSLATE}
|
||||
text="Finalize aggregations"
|
||||
|
@ -401,15 +429,6 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
changeQueryContext({ ...queryContext, finalizeAggregations })
|
||||
}
|
||||
/>
|
||||
<MenuTristate
|
||||
icon={IconNames.STOPWATCH}
|
||||
text="Wait until segments have loaded"
|
||||
value={waitUntilSegmentsLoad}
|
||||
undefinedEffectiveValue={ingestMode}
|
||||
onValueChange={waitUntilSegmentsLoad =>
|
||||
changeQueryContext({ ...queryContext, waitUntilSegmentsLoad })
|
||||
}
|
||||
/>
|
||||
<MenuTristate
|
||||
icon={IconNames.FORK}
|
||||
text="Enable GroupBy multi-value unnesting"
|
||||
|
@ -477,15 +496,6 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
})
|
||||
}
|
||||
/>
|
||||
<MenuItem
|
||||
icon={IconNames.TH_DERIVED}
|
||||
text="Edit index spec"
|
||||
label={summarizeIndexSpec(indexSpec)}
|
||||
shouldDismissPopover={false}
|
||||
onClick={() => {
|
||||
setIndexSpecDialogSpec(indexSpec || {});
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
|
@ -602,7 +612,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) {
|
|||
)}
|
||||
{moreMenu && (
|
||||
<Popover position={Position.BOTTOM_LEFT} content={moreMenu}>
|
||||
<Button small={small} minimal={small} rightIcon={IconNames.MORE} />
|
||||
<Button rightIcon={IconNames.MORE} />
|
||||
</Popover>
|
||||
)}
|
||||
{editContextDialogOpen && (
|
||||
|
|
Loading…
Reference in New Issue