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 05346a9  allow semicolon with comment (#7892)
05346a9 is described below

commit 05346a9e0c836f303a36939965d58813c574bef4
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Fri Jun 14 07:53:19 2019 -0700

    allow semicolon with comment (#7892)
---
 web-console/script/create-sql-function-doc.js    | 70 ++++++++++++------------
 web-console/src/views/sql-view/sql-view.spec.tsx |  6 ++
 web-console/src/views/sql-view/sql-view.tsx      |  6 +-
 3 files changed, 45 insertions(+), 37 deletions(-)

diff --git a/web-console/script/create-sql-function-doc.js 
b/web-console/script/create-sql-function-doc.js
index 66d1c3d..dc55989 100755
--- a/web-console/script/create-sql-function-doc.js
+++ b/web-console/script/create-sql-function-doc.js
@@ -19,10 +19,11 @@
  */
 
 const fs = require('fs-extra');
+
 const readfile = '../docs/content/querying/sql.md';
 const writefile = 'lib/sql-function-doc.ts';
 
-const license = `/*
+const heading = `/*
  * 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
@@ -38,61 +39,62 @@ const license = `/*
  * 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.
- */`
-
-const comment = `// This file is auto generated and should not be modified`;
+ */
 
-const disableTSlint = '/* tslint:disable */';
+// This file is auto generated and should not be modified
 
-const interfaceStr = `export interface FunctionDescription {
+export interface FunctionDescription {
   syntax: string;
   description: string;
-}`;
+}
+
+/* tslint:disable:quotemark */
 
-const heading = 
`${license}\n\n${comment}\n\n${interfaceStr}\n\n${disableTSlint}\n\n`;
+export const SQLFunctionDoc: FunctionDescription[] = `;
 
 const readDoc = async () => {
   try {
-    let content = `${heading}export const SQLFunctionDoc: 
FunctionDescription[] = [ \n`;
-
     const data = await fs.readFile(readfile, 'utf-8');
-    const sections = data.toString().split("##");
+    const sections = data.split("##");
 
+    let entries = [];
     sections.forEach((section) => {
+      if (!/^#.*function/.test(section)) return;
 
-      if (/^#.*functions/.test(section)) {
-
-        section.split('\n').forEach(line => {
+      entries = entries.concat(
+        section.split('\n').map(line => {
           if (line.startsWith('|`')) {
-            const rawSyntax = line.match(/\|`.*`\|/g);
-            if (rawSyntax == null) return;
-            const syntax = rawSyntax[0].slice(2, -2).replace(/\\/g,'');
+            const rawSyntax = line.match(/\|`(.*)`\|/);
+            if (rawSyntax == null) return null;
+            const syntax = rawSyntax[1]
+              .replace(/\\/g,'')
+              .replace(/&#124;/g,'|');
+
+            // Must have an uppercase letter
+            if (!/[A-Z]/.test(syntax)) return null;
 
-            const rawDescription = line.match(/`\|.*\|/g);
-            if (rawDescription == null) return;
-            const description = rawDescription[0].slice(2,-1);
+            const rawDescription = line.match(/`\|(.*)\|/);
+            if (rawDescription == null) return null;
+            const description = rawDescription[1];
 
-            const json = {
+            return {
               syntax: syntax,
               description: description
-            }
-
-            const prettyJson = JSON.stringify(json, null, 4)
-              .replace('{', '  {')
-              .replace('}', '  }')
-              .replace(/\"([^(\")"]+)\":/g,"$1:");
-            content += `${prettyJson},\n`;
+            };
           }
-        });
-
-      }
+        }).filter(Boolean)
+      );
     });
 
-    content = content.slice(0, -2);
-    content += '\n];\n';
+    // Make sure there are at least 10 functions for sanity
+    if (entries.length < 10) {
+      throw new Error(`Did not find any entries did the structure of 
'${readfile}' change?`);
+    }
+
+    const content = heading + JSON.stringify(entries, null, 2) + ';\n';
 
     try {
-      fs.writeFile(writefile, content, 'utf-8');
+      await fs.writeFile(writefile, content, 'utf-8');
     } catch (e) {
       console.log(`Error when writing to ${writefile}: `, e);
     }
diff --git a/web-console/src/views/sql-view/sql-view.spec.tsx 
b/web-console/src/views/sql-view/sql-view.spec.tsx
index c3801d3..e5809a8 100644
--- a/web-console/src/views/sql-view/sql-view.spec.tsx
+++ b/web-console/src/views/sql-view/sql-view.spec.tsx
@@ -29,4 +29,10 @@ describe('sql view', () => {
       />);
     expect(sqlView).toMatchSnapshot();
   });
+
+  it('trimSemicolon', () => {
+    expect(SqlView.trimSemicolon('SELECT * FROM tbl;')).toEqual('SELECT * FROM 
tbl');
+    expect(SqlView.trimSemicolon('SELECT * FROM tbl;   ')).toEqual('SELECT * 
FROM tbl   ');
+    expect(SqlView.trimSemicolon('SELECT * FROM tbl; --hello  
')).toEqual('SELECT * FROM tbl --hello  ');
+  });
 });
diff --git a/web-console/src/views/sql-view/sql-view.tsx 
b/web-console/src/views/sql-view/sql-view.tsx
index fedd243..43f3262 100644
--- a/web-console/src/views/sql-view/sql-view.tsx
+++ b/web-console/src/views/sql-view/sql-view.tsx
@@ -67,7 +67,7 @@ interface SqlQueryResult {
 export class SqlView extends React.PureComponent<SqlViewProps, SqlViewState> {
   static trimSemicolon(query: string): string {
     // Trims out a trailing semicolon while preserving space 
(https://bit.ly/1n1yfkJ)
-    return query.replace(/;+(\s*)$/, '$1');
+    return query.replace(/;+((?:\s*--[^\n]*)?\s*)$/, '$1');
   }
 
   private sqlQueryManager: QueryManager<QueryWithContext, SqlQueryResult>;
@@ -106,7 +106,7 @@ export class SqlView extends 
React.PureComponent<SqlViewProps, SqlViewState> {
 
         } else {
           const actualQuery = wrapQuery ?
-            `SELECT * FROM (${SqlView.trimSemicolon(queryString)}) LIMIT 2000` 
:
+            `SELECT * FROM (${SqlView.trimSemicolon(queryString)}\n) LIMIT 
2000` :
             queryString;
 
           const queryPayload: Record<string, any> = {
@@ -141,7 +141,7 @@ export class SqlView extends 
React.PureComponent<SqlViewProps, SqlViewState> {
       processQuery: async (queryWithContext: QueryWithContext) => {
         const { queryString, context } = queryWithContext;
         const explainPayload: Record<string, any> = {
-          query: `EXPLAIN PLAN FOR (${SqlView.trimSemicolon(queryString)})`,
+          query: `EXPLAIN PLAN FOR (${SqlView.trimSemicolon(queryString)}\n)`,
           resultFormat: 'object'
         };
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to