mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
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 <fletcher.haynes@generalassemb.ly>
(cherry picked from commit 7ab453e289)
This commit is contained in:
parent
4e3856348c
commit
bf0486503a
5 changed files with 61 additions and 14 deletions
|
|
@ -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<QueryProps> = ({
|
|||
results,
|
||||
error,
|
||||
loading,
|
||||
isSQL3,
|
||||
onRemoveResult,
|
||||
onClear,
|
||||
onQuery
|
||||
|
|
@ -172,6 +174,7 @@ export const Query: FC<QueryProps> = ({
|
|||
{results.map((result, idx) => (
|
||||
<Paper key={`query-result-${idx}`} className={css.results}>
|
||||
<QueryResults
|
||||
isSQL3={isSQL3}
|
||||
collapsibleQuery={false}
|
||||
results={result}
|
||||
onRemoveResult={() => onRemoveResult(idx)}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export const QueryContainer: FC<{}> = () => {
|
|||
const [results, setResults] = useState<ResultType[]>([]);
|
||||
const [errorResult, setErrorResult] = useState<ResultType>();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [isSQL3, setIsSQL3] = useState<boolean>(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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ import css from './QueryResults.module.scss';
|
|||
type QueryResultsProps = {
|
||||
collapsibleQuery?: boolean;
|
||||
results: ResultType;
|
||||
isSQL3?: boolean
|
||||
onRemoveResult?: () => void;
|
||||
};
|
||||
|
||||
export const QueryResults: FC<QueryResultsProps> = ({
|
||||
collapsibleQuery = true,
|
||||
results,
|
||||
isSQL3,
|
||||
onRemoveResult,
|
||||
}) => {
|
||||
const [showQuery, setShowQuery] = useState<boolean>(false);
|
||||
|
|
@ -31,22 +33,38 @@ export const QueryResults: FC<QueryResultsProps> = ({
|
|||
|
||||
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`];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,4 +25,4 @@ export const querySQL = (sql: string, onMessage, onEnd) => {
|
|||
const querySQLRequest = new QuerySQLRequest();
|
||||
querySQLRequest.setSql(sql);
|
||||
invokeStream(Pilosa.QuerySQL, querySQLRequest, onMessage, onEnd);
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue