Skip to content

Commit 05346a9

Browse files
vogievetskyfjy
authored andcommitted
allow semicolon with comment (#7892)
1 parent 456a365 commit 05346a9

File tree

3 files changed

+45
-37
lines changed

3 files changed

+45
-37
lines changed

web-console/script/create-sql-function-doc.js

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
*/
2020

2121
const fs = require('fs-extra');
22+
2223
const readfile = '../docs/content/querying/sql.md';
2324
const writefile = 'lib/sql-function-doc.ts';
2425

25-
const license = `/*
26+
const heading = `/*
2627
* Licensed to the Apache Software Foundation (ASF) under one
2728
* or more contributor license agreements. See the NOTICE file
2829
* distributed with this work for additional information
@@ -38,61 +39,62 @@ const license = `/*
3839
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3940
* See the License for the specific language governing permissions and
4041
* limitations under the License.
41-
*/`
42-
43-
const comment = `// This file is auto generated and should not be modified`;
42+
*/
4443
45-
const disableTSlint = '/* tslint:disable */';
44+
// This file is auto generated and should not be modified
4645
47-
const interfaceStr = `export interface FunctionDescription {
46+
export interface FunctionDescription {
4847
syntax: string;
4948
description: string;
50-
}`;
49+
}
50+
51+
/* tslint:disable:quotemark */
5152
52-
const heading = `${license}\n\n${comment}\n\n${interfaceStr}\n\n${disableTSlint}\n\n`;
53+
export const SQLFunctionDoc: FunctionDescription[] = `;
5354

5455
const readDoc = async () => {
5556
try {
56-
let content = `${heading}export const SQLFunctionDoc: FunctionDescription[] = [ \n`;
57-
5857
const data = await fs.readFile(readfile, 'utf-8');
59-
const sections = data.toString().split("##");
58+
const sections = data.split("##");
6059

60+
let entries = [];
6161
sections.forEach((section) => {
62+
if (!/^#.*function/.test(section)) return;
6263

63-
if (/^#.*functions/.test(section)) {
64-
65-
section.split('\n').forEach(line => {
64+
entries = entries.concat(
65+
section.split('\n').map(line => {
6666
if (line.startsWith('|`')) {
67-
const rawSyntax = line.match(/\|`.*`\|/g);
68-
if (rawSyntax == null) return;
69-
const syntax = rawSyntax[0].slice(2, -2).replace(/\\/g,'');
67+
const rawSyntax = line.match(/\|`(.*)`\|/);
68+
if (rawSyntax == null) return null;
69+
const syntax = rawSyntax[1]
70+
.replace(/\\/g,'')
71+
.replace(/|/g,'|');
72+
73+
// Must have an uppercase letter
74+
if (!/[A-Z]/.test(syntax)) return null;
7075

71-
const rawDescription = line.match(/`\|.*\|/g);
72-
if (rawDescription == null) return;
73-
const description = rawDescription[0].slice(2,-1);
76+
const rawDescription = line.match(/`\|(.*)\|/);
77+
if (rawDescription == null) return null;
78+
const description = rawDescription[1];
7479

75-
const json = {
80+
return {
7681
syntax: syntax,
7782
description: description
78-
}
79-
80-
const prettyJson = JSON.stringify(json, null, 4)
81-
.replace('{', ' {')
82-
.replace('}', ' }')
83-
.replace(/\"([^(\")"]+)\":/g,"$1:");
84-
content += `${prettyJson},\n`;
83+
};
8584
}
86-
});
87-
88-
}
85+
}).filter(Boolean)
86+
);
8987
});
9088

91-
content = content.slice(0, -2);
92-
content += '\n];\n';
89+
// Make sure there are at least 10 functions for sanity
90+
if (entries.length < 10) {
91+
throw new Error(`Did not find any entries did the structure of '${readfile}' change?`);
92+
}
93+
94+
const content = heading + JSON.stringify(entries, null, 2) + ';\n';
9395

9496
try {
95-
fs.writeFile(writefile, content, 'utf-8');
97+
await fs.writeFile(writefile, content, 'utf-8');
9698
} catch (e) {
9799
console.log(`Error when writing to ${writefile}: `, e);
98100
}

web-console/src/views/sql-view/sql-view.spec.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,10 @@ describe('sql view', () => {
2929
/>);
3030
expect(sqlView).toMatchSnapshot();
3131
});
32+
33+
it('trimSemicolon', () => {
34+
expect(SqlView.trimSemicolon('SELECT * FROM tbl;')).toEqual('SELECT * FROM tbl');
35+
expect(SqlView.trimSemicolon('SELECT * FROM tbl; ')).toEqual('SELECT * FROM tbl ');
36+
expect(SqlView.trimSemicolon('SELECT * FROM tbl; --hello ')).toEqual('SELECT * FROM tbl --hello ');
37+
});
3238
});

web-console/src/views/sql-view/sql-view.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ interface SqlQueryResult {
6767
export class SqlView extends React.PureComponent<SqlViewProps, SqlViewState> {
6868
static trimSemicolon(query: string): string {
6969
// Trims out a trailing semicolon while preserving space (https://bit.ly/1n1yfkJ)
70-
return query.replace(/;+(\s*)$/, '$1');
70+
return query.replace(/;+((?:\s*--[^\n]*)?\s*)$/, '$1');
7171
}
7272

7373
private sqlQueryManager: QueryManager<QueryWithContext, SqlQueryResult>;
@@ -106,7 +106,7 @@ export class SqlView extends React.PureComponent<SqlViewProps, SqlViewState> {
106106

107107
} else {
108108
const actualQuery = wrapQuery ?
109-
`SELECT * FROM (${SqlView.trimSemicolon(queryString)}) LIMIT 2000` :
109+
`SELECT * FROM (${SqlView.trimSemicolon(queryString)}\n) LIMIT 2000` :
110110
queryString;
111111

112112
const queryPayload: Record<string, any> = {
@@ -141,7 +141,7 @@ export class SqlView extends React.PureComponent<SqlViewProps, SqlViewState> {
141141
processQuery: async (queryWithContext: QueryWithContext) => {
142142
const { queryString, context } = queryWithContext;
143143
const explainPayload: Record<string, any> = {
144-
query: `EXPLAIN PLAN FOR (${SqlView.trimSemicolon(queryString)})`,
144+
query: `EXPLAIN PLAN FOR (${SqlView.trimSemicolon(queryString)}\n)`,
145145
resultFormat: 'object'
146146
};
147147

0 commit comments

Comments
 (0)