From bf0486503a3855df3711e97609831b47c395b963 Mon Sep 17 00:00:00 2001 From: Fletcher Haynes Date: Thu, 8 Dec 2022 12:47:21 -0800 Subject: [PATCH] This adds in support to the lattice UI application to use the SQL3 (#2338) * This adds in support to the lattice UI application to use the SQL3 endpoint. If the `/sql` endpoint returns 404, it will use the SQL1 endpoint. If the `/sql` endpoint is available, it will send SQL queries to that. It does not try the SQL1 endpoint if the SQL3 endpoint returns an error processing the query. That is, it is all SQL3 or SQL1. - Below are the specific changes: - Adds a file that contains functions for interacting with http services as opposed to just grpc/event-based services. As of this commit, it is only the SQL3 endpoint. - This adds a variable to track if we are using the SQL3 endpoint or not - This adds a function to handle the response from the SQL3 endpoint - Adds a function to eventServices to query the sql3 HTTP endpoint - Fixed a missing semicolon in grpcServices Co-authored-by: Fletcher Haynes (cherry picked from commit 7ab453e289c41805278aece4f21470f2d96b5a2a) --- lattice/src/App/Query/Query.tsx | 3 ++ lattice/src/App/Query/QueryContainer.tsx | 25 +++++++++++- .../App/Query/QueryResults/QueryResults.tsx | 40 ++++++++++++++----- lattice/src/services/eventServices.tsx | 5 ++- lattice/src/services/grpcServices.tsx | 2 +- 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/lattice/src/App/Query/Query.tsx b/lattice/src/App/Query/Query.tsx index edc52caa9..038a9c614 100644 --- a/lattice/src/App/Query/Query.tsx +++ b/lattice/src/App/Query/Query.tsx @@ -27,6 +27,7 @@ type QueryProps = { results: ResultType[]; error?: ResultType; loading: boolean; + isSQL3: boolean; onRemoveResult: (resultIdx: number) => void; onClear: () => void; onQuery: (query: string, type: 'PQL' | 'SQL', index?: string) => void; @@ -37,6 +38,7 @@ export const Query: FC = ({ results, error, loading, + isSQL3, onRemoveResult, onClear, onQuery @@ -172,6 +174,7 @@ export const Query: FC = ({ {results.map((result, idx) => ( onRemoveResult(idx)} diff --git a/lattice/src/App/Query/QueryContainer.tsx b/lattice/src/App/Query/QueryContainer.tsx index 45401a7ca..c07df10df 100644 --- a/lattice/src/App/Query/QueryContainer.tsx +++ b/lattice/src/App/Query/QueryContainer.tsx @@ -41,6 +41,7 @@ export const QueryContainer: FC<{}> = () => { const [results, setResults] = useState([]); const [errorResult, setErrorResult] = useState(); const [loading, setLoading] = useState(false); + const [isSQL3, setIsSQL3] = useState(false) useEffectOnce(() => { pilosa.get.schema().then((res) => { @@ -48,6 +49,15 @@ export const QueryContainer: FC<{}> = () => { }); }); + const handleHTTPQueryMessages = (response) => { + setIsSQL3(true) + streamingResults.headers = response.data.schema.fields; + streamingResults.rows = response.data.data; + setErrorResult(undefined); + setResults([streamingResults]); + setLoading(false); + } + const handleQueryMessages = (message: RowResponse) => { if (streamingResults.totalMessageCount < MAX_MESSAGES) { const response = message.toObject(); @@ -84,6 +94,7 @@ export const QueryContainer: FC<{}> = () => { streamingResults.roundtrip = moment .duration(moment().diff(startTime)) .as('milliseconds'); + setErrorResult(undefined); setResults([streamingResults, ...results]); } @@ -119,7 +130,18 @@ export const QueryContainer: FC<{}> = () => { setLoading(false); } } else { - querySQL(query, handleQueryMessages, handleQueryEnd); + pilosa.post.sql(query) + .then((res) => { + setIsSQL3(true); + handleHTTPQueryMessages(res); + }).catch((e) => { + if (e.response.status === 404) { + setIsSQL3(false); + querySQL(query, handleQueryMessages, handleQueryEnd); + } + + + }); } } }; @@ -139,6 +161,7 @@ export const QueryContainer: FC<{}> = () => { loading={loading} onClear={() => setResults([])} onRemoveResult={removeResultItem} + isSQL3={isSQL3} /> ); }; diff --git a/lattice/src/App/Query/QueryResults/QueryResults.tsx b/lattice/src/App/Query/QueryResults/QueryResults.tsx index 33c016f09..33fcd278b 100644 --- a/lattice/src/App/Query/QueryResults/QueryResults.tsx +++ b/lattice/src/App/Query/QueryResults/QueryResults.tsx @@ -14,12 +14,14 @@ import css from './QueryResults.module.scss'; type QueryResultsProps = { collapsibleQuery?: boolean; results: ResultType; + isSQL3?: boolean onRemoveResult?: () => void; }; export const QueryResults: FC = ({ collapsibleQuery = true, results, + isSQL3, onRemoveResult, }) => { const [showQuery, setShowQuery] = useState(false); @@ -31,22 +33,38 @@ export const QueryResults: FC = ({ const headers = results.headers; const data = results.rows.map((row) => { + let rowData = {}; row.forEach((col, colIdx) => { - const header = headers[colIdx]; - if (header.datatype.includes('[]')) { - const dataTypeVal = `${header.datatype.slice(2)}arrayval`; - rowData[header.name] = col[dataTypeVal].valsList.join(', '); - } else if (header.datatype === 'decimal') { - const decimalVal = col[`${header.datatype}val`]; - if (decimalVal) { - const { value, scale } = decimalVal; - rowData[header.name] = value / Math.pow(10, scale); + + if (isSQL3) { + const header = headers[colIdx]; + if (Array.isArray(col)) { + let displayString = col.join(", "); + rowData[header.name] = displayString; + } else if (headers[colIdx]['base-type'] == "decimal") { + const scale = headers[colIdx]['type-info']['scale']; + rowData[header.name] = Number(col) / Math.pow(10, scale); } else { - rowData[header.name] = decimalVal; + rowData[header.name] = col; } + } else { - rowData[header.name] = col[`${header.datatype}val`]; + const header = headers[colIdx]; + if (header.datatype.includes('[]')) { + const dataTypeVal = `${header.datatype.slice(2)}arrayval`; + rowData[header.name] = col[dataTypeVal].valsList.join(', '); + } else if (header.datatype === 'decimal') { + const decimalVal = col[`${header.datatype}val`]; + if (decimalVal) { + const { value, scale } = decimalVal; + rowData[header.name] = value / Math.pow(10, scale); + } else { + rowData[header.name] = decimalVal; + } + } else { + rowData[header.name] = col[`${header.datatype}val`]; + } } }); diff --git a/lattice/src/services/eventServices.tsx b/lattice/src/services/eventServices.tsx index a3a56e189..766545616 100644 --- a/lattice/src/services/eventServices.tsx +++ b/lattice/src/services/eventServices.tsx @@ -44,7 +44,7 @@ export const pilosa = { }, queryHistory() { return api.get('/query-history'); - }, + } }, post: { finishTransaction(id) { @@ -53,5 +53,8 @@ export const pilosa = { query(index, query) { return api.post(`/index/${index}/query`, query); }, + sql(query) { + return api.post(`/sql`, query); + } }, }; diff --git a/lattice/src/services/grpcServices.tsx b/lattice/src/services/grpcServices.tsx index 03f667c34..3e580aa5b 100644 --- a/lattice/src/services/grpcServices.tsx +++ b/lattice/src/services/grpcServices.tsx @@ -25,4 +25,4 @@ export const querySQL = (sql: string, onMessage, onEnd) => { const querySQLRequest = new QuerySQLRequest(); querySQLRequest.setSql(sql); invokeStream(Pilosa.QuerySQL, querySQLRequest, onMessage, onEnd); -} +}; \ No newline at end of file