diff --git a/README-zh_CN.md b/README-zh_CN.md
index aab75a00..fec76452 100644
--- a/README-zh_CN.md
+++ b/README-zh_CN.md
@@ -39,6 +39,7 @@ Monaco SQL Languages 是一个基于 Monaco Editor 的 SQL 语言项目,从 [m
- Trino (Presto)
- PostgreSQL
- Impala
+- GenericSQL
@@ -72,6 +73,7 @@ npm install monaco-sql-languages
import 'monaco-sql-languages/esm/languages/trino/trino.contribution';
import 'monaco-sql-languages/esm/languages/pgsql/pgsql.contribution';
import 'monaco-sql-languages/esm/languages/impala/impala.contribution';
+ import 'monaco-sql-languages/esm/languages/generic/generic.contribution';
// 或者你可以通过下面的方式一次性导入所有的语言功能
// import 'monaco-sql-languages/esm/all.contributions';
diff --git a/README.md b/README.md
index 49268932..e7264c32 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ This project is based on the SQL language project of Monaco Editor, which was fo
- Trino (Presto)
- PostgreSQL
- Impala
+- GenericSQL
@@ -71,6 +72,7 @@ npm install monaco-sql-languages
import 'monaco-sql-languages/esm/languages/trino/trino.contribution';
import 'monaco-sql-languages/esm/languages/pgsql/pgsql.contribution';
import 'monaco-sql-languages/esm/languages/impala/impala.contribution';
+ import 'monaco-sql-languages/esm/languages/generic/generic.contribution';
// Or you can import all language contributions at once.
// import 'monaco-sql-languages/esm/all.contributions';
diff --git a/package.json b/package.json
index ee3ccfe1..8e2b4eeb 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,8 @@
"postgresql",
"flink",
"trino",
- "impala"
+ "impala",
+ "generic"
],
"repository": {
"type": "git",
@@ -84,6 +85,6 @@
]
},
"dependencies": {
- "dt-sql-parser": "4.4.2"
+ "dt-sql-parser": "4.5.0-beta.2"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8ce50c9d..5d0cb567 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,8 +9,8 @@ importers:
.:
dependencies:
dt-sql-parser:
- specifier: 4.4.2
- version: 4.4.2(antlr4ng-cli@1.0.7)
+ specifier: 4.5.0-beta.2
+ version: 4.5.0-beta.2(antlr4ng-cli@1.0.7)
devDependencies:
'@commitlint/cli':
specifier: ^17.7.2
@@ -714,8 +714,8 @@ packages:
resolution: {integrity: sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==}
engines: {node: '>=6'}
- dt-sql-parser@4.4.2:
- resolution: {integrity: sha512-NpfSeCetxDICs5NNOHKO/e/PTQ/EFnGW0QBo11e5nmuWqVRACZkArcBH9/LKnoe1Mdtql45U5h0aU9GOqhBLWg==}
+ dt-sql-parser@4.5.0-beta.2:
+ resolution: {integrity: sha512-mf2ja7dMFPIk1P5/LzvcRk6mxoRDjdwokITTwklKEWpiNngj5Y/GVlfVb+v3/XekWShPMqrorbRxhxbkuyTA+g==}
engines: {node: '>=18'}
eastasianwidth@0.2.0:
@@ -2729,7 +2729,7 @@ snapshots:
find-up: 3.0.0
minimatch: 3.1.2
- dt-sql-parser@4.4.2(antlr4ng-cli@1.0.7):
+ dt-sql-parser@4.5.0-beta.2(antlr4ng-cli@1.0.7):
dependencies:
antlr4-c3: 3.3.7(antlr4ng-cli@1.0.7)
antlr4ng: 2.0.11(antlr4ng-cli@1.0.7)
diff --git a/src/all.contributions.ts b/src/all.contributions.ts
index 8989152f..6b43abe3 100644
--- a/src/all.contributions.ts
+++ b/src/all.contributions.ts
@@ -5,3 +5,4 @@ import './languages/trino/trino.contribution';
import './languages/mysql/mysql.contribution';
import './languages/pgsql/pgsql.contribution';
import './languages/impala/impala.contribution';
+import './languages/generic/generic.contribution';
diff --git a/src/common/constants.ts b/src/common/constants.ts
index c8f7d8ee..eb8ab9ea 100644
--- a/src/common/constants.ts
+++ b/src/common/constants.ts
@@ -37,5 +37,6 @@ export enum LanguageIdEnum {
PG = 'pgsql',
SPARK = 'sparksql',
TRINO = 'trinosql',
- IMPALA = 'impalasql'
+ IMPALA = 'impalasql',
+ GENERIC = 'genericsql'
}
diff --git a/src/languageFeatures.ts b/src/languageFeatures.ts
index d19a1960..d3877b37 100644
--- a/src/languageFeatures.ts
+++ b/src/languageFeatures.ts
@@ -255,7 +255,9 @@ export class DefinitionAdapter implements languages.Def
startIndex: -1,
endIndex: -1,
startColumn: -1,
- endColumn: -1
+ endColumn: -1,
+ startTokenIndex: -1,
+ endTokenIndex: -1
};
const curEntity = entities?.find((entity: EntityContext) => {
const entityPosition = entity.position;
diff --git a/src/languages/generic/generic.contribution.ts b/src/languages/generic/generic.contribution.ts
new file mode 100644
index 00000000..f474843d
--- /dev/null
+++ b/src/languages/generic/generic.contribution.ts
@@ -0,0 +1,18 @@
+import { registerLanguage } from '../../_.contribution';
+import { LanguageIdEnum } from '../../common/constants';
+import { setupLanguageFeatures } from '../../setupLanguageFeatures';
+
+registerLanguage({
+ id: LanguageIdEnum.GENERIC,
+ extensions: ['.genericsql'],
+ aliases: ['GenericSQL', 'generic', 'Generic'],
+ loader: () => import('./generic')
+});
+
+setupLanguageFeatures(LanguageIdEnum.GENERIC, {
+ completionItems: true,
+ diagnostics: false,
+ references: false,
+ definitions: false,
+ hover: false
+});
diff --git a/src/languages/generic/generic.snippet.ts b/src/languages/generic/generic.snippet.ts
new file mode 100644
index 00000000..5c803966
--- /dev/null
+++ b/src/languages/generic/generic.snippet.ts
@@ -0,0 +1,76 @@
+import type { CompletionSnippetOption } from 'src/monaco.contribution';
+
+export const genericSnippets: CompletionSnippetOption[] = [
+ {
+ label: 'select',
+ prefix: 'SELECT',
+ body: ['SELECT ${2:column1}, ${3:column2} FROM ${1:table_name};\n$4']
+ },
+ {
+ label: 'select-join',
+ prefix: 'SELECT-JOIN',
+ body: [
+ 'SELECT ${8:column1} FROM ${1:table_name1} ${2:t1}',
+ '${3:LEFT} JOIN ${4:table_name2} ${5:t2} ON ${2:t1}.${6:column1} = ${5:t2}.${7:column2};\n$9'
+ ]
+ },
+ {
+ label: 'select-order-by',
+ prefix: 'SELECT-ORDER-BY',
+ body: [
+ 'SELECT ${2:column1}, ${3:column2} FROM ${1:table_name} ORDER BY ${4:column1} ${5:desc};\n$6'
+ ]
+ },
+ {
+ label: 'select-group-by',
+ prefix: 'SELECT-GROUP-BY',
+ body: ['SELECT ${2:column1}, COUNT(*) FROM ${1:table_name} GROUP BY ${2:column1};\n$3']
+ },
+ {
+ label: 'insert',
+ prefix: 'INSERT-INTO',
+ body: [
+ 'INSERT INTO ${1:table_name} (${2:column1}, ${3:column2})',
+ 'SELECT ${4:column1}, ${5:column2} FROM ${6:source_table};\n$7'
+ ]
+ },
+ {
+ label: 'update',
+ prefix: 'UPDATE',
+ body: [
+ 'UPDATE ${1:table_name}',
+ 'SET ${2:column1} = ${3:value1}',
+ 'WHERE ${4:column2} = ${5:value2};\n$6'
+ ]
+ },
+ {
+ label: 'delete',
+ prefix: 'DELETE',
+ body: ['DELETE FROM ${1:table_name}', 'WHERE ${2:column1} = ${3:value1};\n$4']
+ },
+ {
+ label: 'create-table',
+ prefix: 'CREATE-TABLE',
+ body: [
+ 'CREATE TABLE IF NOT EXISTS ${1:table_name} (',
+ '\t${2:column1} ${3:INT} PRIMARY KEY,',
+ '\t${4:column2} ${5:VARCHAR(100)} NOT NULL',
+ ');\n$6'
+ ]
+ },
+ {
+ label: 'alter-table-add',
+ prefix: 'ALTER-TABLE-ADD',
+ body: ['ALTER TABLE ${1:table_name} ADD COLUMN ${2:column_name} ${3:INT};\n$4']
+ },
+ {
+ label: 'alter-table-drop',
+ prefix: 'ALTER-TABLE-DROP',
+ body: ['ALTER TABLE ${1:table_name} DROP COLUMN ${2:column_name};\n$3']
+ },
+ {
+ label: 'drop-table',
+ prefix: 'DROP-TABLE',
+ body: ['DROP TABLE IF EXISTS ${1:table_name};\n$2']
+ }
+];
diff --git a/src/languages/generic/generic.ts b/src/languages/generic/generic.ts
new file mode 100644
index 00000000..ccf3a548
--- /dev/null
+++ b/src/languages/generic/generic.ts
@@ -0,0 +1,266 @@
+import type { languages } from '../../fillers/monaco-editor-core';
+import { TokenClassConsts } from '../../common/constants';
+
+export const conf: languages.LanguageConfiguration = {
+ comments: {
+ lineComment: '--',
+ blockComment: ['/*', '*/']
+ },
+ brackets: [
+ ['{', '}'],
+ ['[', ']'],
+ ['(', ')']
+ ],
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"' },
+ { open: "'", close: "'" },
+ { open: '`', close: '`' }
+ ],
+ surroundingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"' },
+ { open: "'", close: "'" },
+ { open: '`', close: '`' }
+ ]
+};
+
+export const language = {
+ defaultToken: '',
+ tokenPostfix: '.sql',
+ ignoreCase: true,
+ brackets: [
+ { open: '[', close: ']', token: TokenClassConsts.DELIMITER_SQUARE },
+ { open: '(', close: ')', token: TokenClassConsts.DELIMITER_PAREN },
+ { open: '{', close: '}', token: TokenClassConsts.DELIMITER_CURLY }
+ ],
+ keywords: [
+ 'ADD',
+ 'ALL',
+ 'ALTER',
+ 'AND',
+ 'AS',
+ 'ASC',
+ 'BETWEEN',
+ 'BY',
+ 'CASE',
+ 'CAST',
+ 'CHECK',
+ 'COALESCE',
+ 'COLUMN',
+ 'CONSTRAINT',
+ 'CREATE',
+ 'CROSS',
+ 'DEFAULT',
+ 'DELETE',
+ 'DESC',
+ 'DISTINCT',
+ 'DROP',
+ 'ELSE',
+ 'END',
+ 'ESCAPE',
+ 'EXCEPT',
+ 'EXISTS',
+ 'FALSE',
+ 'FIRST',
+ 'FOREIGN',
+ 'FROM',
+ 'FULL',
+ 'GROUP',
+ 'HAVING',
+ 'IF',
+ 'IN',
+ 'INNER',
+ 'INSERT',
+ 'INTERSECT',
+ 'INTO',
+ 'IS',
+ 'JOIN',
+ 'KEY',
+ 'LAST',
+ 'LEFT',
+ 'LIKE',
+ 'LIMIT',
+ 'NOT',
+ 'NULL',
+ 'NULLIF',
+ 'NULLS',
+ 'OFFSET',
+ 'ON',
+ 'OR',
+ 'ORDER',
+ 'OUTER',
+ 'PRIMARY',
+ 'RECURSIVE',
+ 'REFERENCES',
+ 'RENAME',
+ 'RIGHT',
+ 'SELECT',
+ 'SET',
+ 'TABLE',
+ 'THEN',
+ 'TO',
+ 'TRUE',
+ 'UNION',
+ 'UNIQUE',
+ 'UPDATE',
+ 'VALUES',
+ 'WHEN',
+ 'WHERE',
+ 'WITH'
+ ],
+ operators: [
+ 'AND',
+ 'BETWEEN',
+ 'IN',
+ 'LIKE',
+ 'NOT',
+ 'EXISTS',
+ 'OR',
+ 'IS',
+ 'UNION',
+ 'INTERSECT',
+ 'EXCEPT',
+ 'JOIN',
+ 'CROSS',
+ 'INNER',
+ 'OUTER',
+ 'FULL',
+ 'LEFT',
+ 'RIGHT'
+ ],
+ builtinFunctions: [
+ 'AVG',
+ 'COUNT',
+ 'FIRST_VALUE',
+ 'LAG',
+ 'LAST_VALUE',
+ 'LEAD',
+ 'MAX',
+ 'MIN',
+ 'NTH_VALUE',
+ 'NTILE',
+ 'PERCENT_RANK',
+ 'RANK',
+ 'ROW_NUMBER',
+ 'SUM',
+ 'STDDEV',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ 'VARIANCE'
+ ],
+ builtinVariables: [
+ // Not supported
+ ],
+ typeKeywords: [
+ 'BOOLEAN',
+ 'TINYINT',
+ 'SMALLINT',
+ 'INT',
+ 'INTEGER',
+ 'BIGINT',
+ 'FLOAT',
+ 'DOUBLE',
+ 'DECIMAL',
+ 'NUMERIC',
+ 'VARCHAR',
+ 'CHAR',
+ 'TEXT',
+ 'DATE',
+ 'TIME',
+ 'TIMESTAMP',
+ 'BINARY',
+ 'VARBINARY'
+ ],
+ scopeKeywords: ['CASE', 'END', 'WHEN', 'THEN', 'ELSE'],
+ pseudoColumns: [
+ // Not supported
+ ],
+ tokenizer: {
+ root: [
+ { include: '@comments' },
+ { include: '@whitespace' },
+ { include: '@pseudoColumns' },
+ { include: '@customParams' },
+ { include: '@numbers' },
+ { include: '@strings' },
+ { include: '@complexIdentifiers' },
+ { include: '@scopes' },
+ [/[:;,.]/, TokenClassConsts.DELIMITER],
+ [/[\(\)\[\]\{\}]/, '@brackets'],
+ [
+ /[\w@]+/,
+ {
+ cases: {
+ '@scopeKeywords': TokenClassConsts.KEYWORD_SCOPE,
+ '@operators': TokenClassConsts.OPERATOR_KEYWORD,
+ '@typeKeywords': TokenClassConsts.TYPE,
+ '@builtinVariables': TokenClassConsts.VARIABLE,
+ '@builtinFunctions': TokenClassConsts.PREDEFINED,
+ '@keywords': TokenClassConsts.KEYWORD,
+ '@default': TokenClassConsts.IDENTIFIER
+ }
+ }
+ ],
+ [/[<>=!%&+\-*/|~^]/, TokenClassConsts.OPERATOR_SYMBOL]
+ ],
+ whitespace: [[/[\s\t\r\n]+/, TokenClassConsts.WHITE]],
+ comments: [
+ [/--+.*/, TokenClassConsts.COMMENT],
+ [/\/\*/, { token: TokenClassConsts.COMMENT_QUOTE, next: '@comment' }]
+ ],
+ comment: [
+ [/[^*/]+/, TokenClassConsts.COMMENT],
+ [/\*\//, { token: TokenClassConsts.COMMENT_QUOTE, next: '@pop' }],
+ [/./, TokenClassConsts.COMMENT]
+ ],
+ pseudoColumns: [
+ [
+ /[$][A-Za-z_][\w@#$]*/,
+ {
+ cases: {
+ '@pseudoColumns': TokenClassConsts.PREDEFINED,
+ '@default': TokenClassConsts.IDENTIFIER
+ }
+ }
+ ]
+ ],
+ customParams: [
+ [/\${[A-Za-z0-9._-]*}/, TokenClassConsts.VARIABLE],
+ [/\@\@{[A-Za-z0-9._-]*}/, TokenClassConsts.VARIABLE]
+ ],
+ numbers: [
+ [/[$][+-]*\d*(\.\d*)?/, TokenClassConsts.NUMBER],
+ [/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, TokenClassConsts.NUMBER]
+ ],
+ strings: [[/'/, { token: TokenClassConsts.STRING, next: '@string' }]],
+ string: [
+ [/[^']+/, TokenClassConsts.STRING_ESCAPE],
+ [/''/, TokenClassConsts.STRING],
+ [/'/, { token: TokenClassConsts.STRING, next: '@pop' }]
+ ],
+ complexIdentifiers: [
+ [/`/, { token: TokenClassConsts.IDENTIFIER_QUOTE, next: '@quotedIdentifier' }],
+ [/"/, { token: TokenClassConsts.IDENTIFIER_QUOTE, next: '@doubleQuotedIdentifier' }]
+ ],
+ quotedIdentifier: [
+ [/[^`]+/, TokenClassConsts.IDENTIFIER_QUOTE],
+ [/``/, TokenClassConsts.IDENTIFIER_QUOTE],
+ [/`/, { token: TokenClassConsts.IDENTIFIER_QUOTE, next: '@pop' }]
+ ],
+ doubleQuotedIdentifier: [
+ [/[^"]+/, TokenClassConsts.IDENTIFIER_QUOTE],
+ [/""/, TokenClassConsts.IDENTIFIER_QUOTE],
+ [/"/, { token: TokenClassConsts.IDENTIFIER_QUOTE, next: '@pop' }]
+ ],
+ scopes: [
+ // Not supported
+ ]
+ }
+};
diff --git a/src/languages/generic/generic.worker.ts b/src/languages/generic/generic.worker.ts
new file mode 100644
index 00000000..e5b8289c
--- /dev/null
+++ b/src/languages/generic/generic.worker.ts
@@ -0,0 +1,11 @@
+import { worker } from '../../fillers/monaco-editor-core';
+import * as EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js';
+import { ICreateData } from '../../baseSQLWorker';
+import { GenericSQLWorker } from './genericWorker';
+
+self.onmessage = () => {
+ // ignore the first message
+ EditorWorker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
+ return new GenericSQLWorker(ctx, createData);
+ });
+};
diff --git a/src/languages/generic/genericWorker.ts b/src/languages/generic/genericWorker.ts
new file mode 100644
index 00000000..776f95e6
--- /dev/null
+++ b/src/languages/generic/genericWorker.ts
@@ -0,0 +1,17 @@
+import { worker } from '../../fillers/monaco-editor-core';
+import { GenericSQL } from 'dt-sql-parser/dist/parser/generic';
+import { BaseSQLWorker, ICreateData } from '../../baseSQLWorker';
+
+export class GenericSQLWorker extends BaseSQLWorker {
+ protected _ctx: worker.IWorkerContext;
+ protected parser: GenericSQL;
+ constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
+ super(ctx, createData);
+ this._ctx = ctx;
+ this.parser = new GenericSQL();
+ }
+}
+
+export function create(ctx: worker.IWorkerContext, createData: ICreateData): GenericSQLWorker {
+ return new GenericSQLWorker(ctx, createData);
+}
diff --git a/src/setupLanguageFeatures.ts b/src/setupLanguageFeatures.ts
index 6e965958..3ef5ef18 100644
--- a/src/setupLanguageFeatures.ts
+++ b/src/setupLanguageFeatures.ts
@@ -109,6 +109,8 @@ function getDefaultSnippets(languageId: LanguageIdEnum) {
return snippets.sparkSnippets;
case LanguageIdEnum.TRINO:
return snippets.trinoSnippets;
+ case LanguageIdEnum.GENERIC:
+ return snippets.genericSnippets;
default:
return [];
}
diff --git a/src/snippets.ts b/src/snippets.ts
index 997e8f28..4174ed3f 100644
--- a/src/snippets.ts
+++ b/src/snippets.ts
@@ -5,3 +5,4 @@ export { pgsqlSnippets } from './languages/pgsql/pgsql.snippet';
export { sparkSnippets } from './languages/spark/spark.snippet';
export { mysqlSnippets } from './languages/mysql/mysql.snippet';
export { impalaSnippets } from './languages/impala/impala.snippet';
+export { genericSnippets } from './languages/generic/generic.snippet';
diff --git a/website/src/consts/index.ts b/website/src/consts/index.ts
index 1cb3fe23..02d38d6e 100644
--- a/website/src/consts/index.ts
+++ b/website/src/consts/index.ts
@@ -38,7 +38,8 @@ export const SQL_LANGUAGES = [
'MySQL',
'PGSQL',
'TrinoSQL',
- 'ImpalaSQL'
+ 'ImpalaSQL',
+ 'GenericSQL'
];
export const defaultLanguage = SQL_LANGUAGES[0];
diff --git a/website/src/languages/index.ts b/website/src/languages/index.ts
index fc52add3..685edca9 100644
--- a/website/src/languages/index.ts
+++ b/website/src/languages/index.ts
@@ -137,3 +137,15 @@ setupLanguageFeatures(LanguageIdEnum.IMPALA, {
hover: true,
preprocessCode
});
+
+setupLanguageFeatures(LanguageIdEnum.GENERIC, {
+ completionItems: {
+ enable: true,
+ completionService
+ },
+ diagnostics: false,
+ references: true,
+ definitions: true,
+ hover: true,
+ preprocessCode
+});
diff --git a/website/src/languages/languageWorker.ts b/website/src/languages/languageWorker.ts
index 53bb10bf..688550bc 100644
--- a/website/src/languages/languageWorker.ts
+++ b/website/src/languages/languageWorker.ts
@@ -9,6 +9,7 @@ import PGSQLWorker from 'monaco-sql-languages/esm/languages/pgsql/pgsql.worker?w
import MySQLWorker from 'monaco-sql-languages/esm/languages/mysql/mysql.worker?worker';
import TrinoSQLWorker from 'monaco-sql-languages/esm/languages/trino/trino.worker?worker';
import ImpalaSQLWorker from 'monaco-sql-languages/esm/languages/impala/impala.worker?worker';
+import GenericSQLWorker from 'monaco-sql-languages/esm/languages/generic/generic.worker?worker';
(globalThis as any).MonacoEnvironment = {
getWorker(_: any, label: string) {
@@ -33,6 +34,9 @@ import ImpalaSQLWorker from 'monaco-sql-languages/esm/languages/impala/impala.wo
if (label === LanguageIdEnum.IMPALA) {
return new ImpalaSQLWorker();
}
+ if (label === LanguageIdEnum.GENERIC) {
+ return new GenericSQLWorker();
+ }
return new EditorWorker();
}
};