diff --git a/Go/Embeddings/Go (Embedded TSQL).sublime-syntax b/Go/Embeddings/Go (Embedded TSQL).sublime-syntax
new file mode 100644
index 0000000000..854c48f25e
--- /dev/null
+++ b/Go/Embeddings/Go (Embedded TSQL).sublime-syntax
@@ -0,0 +1,19 @@
+%YAML 1.2
+---
+name: Go (Embedded T-SQL)
+scope: source.go.embedded-backtick-string.tsql
+version: 2
+hidden: true
+
+extends: Packages/Go/Embeddings/Go (Embedded Backtick String).sublime-syntax
+
+contexts:
+ match-raw-string:
+ # replaces Go.sublime-syntax#match-raw-string
+ - match: '`'
+ scope: meta.string.go string.quoted.backtick.go punctuation.definition.string.begin.go
+ embed: scope:source.tsql.go-embedded-backtick-string
+ embed_scope: meta.string.go meta.embedded.go source.sql.embedded.go
+ escape: '`'
+ escape_captures:
+ 0: meta.string.go string.quoted.backtick.go punctuation.definition.string.end.go
diff --git a/Go/Embeddings/SQL (for Go Embedded Backtick Strings).sublime-syntax b/Go/Embeddings/SQL (for Go Embedded Backtick Strings).sublime-syntax
index e128b0cd6a..00e4668473 100644
--- a/Go/Embeddings/SQL (for Go Embedded Backtick Strings).sublime-syntax
+++ b/Go/Embeddings/SQL (for Go Embedded Backtick Strings).sublime-syntax
@@ -2,7 +2,7 @@
---
name: SQL inside Go backtick string
scope: source.sql.go-embedded-backtick-string
-version: 1
+version: 2
hidden: true
extends: Packages/SQL/SQL.sublime-syntax
diff --git a/Go/Embeddings/TSQL (for Go Embedded Backtick Strings).sublime-syntax b/Go/Embeddings/TSQL (for Go Embedded Backtick Strings).sublime-syntax
new file mode 100644
index 0000000000..57128ea3ff
--- /dev/null
+++ b/Go/Embeddings/TSQL (for Go Embedded Backtick Strings).sublime-syntax
@@ -0,0 +1,21 @@
+%YAML 1.2
+---
+name: T-SQL inside Go backtick string
+scope: source.tsql.go-embedded-backtick-string
+version: 2
+hidden: true
+
+extends: Packages/SQL/TSQL.sublime-syntax
+
+contexts:
+ prototype:
+ - meta_prepend: true
+ - include: scope:source.go#match-raw-text-content
+
+ string-escape:
+ - meta_prepend: true
+ - include: scope:source.go#match-raw-string-content
+
+ string-interpolation:
+ - meta_prepend: true
+ - include: scope:source.go#match-raw-string-content
diff --git a/Go/Go.sublime-syntax b/Go/Go.sublime-syntax
index 950a6f9b4e..62e97bb5c4 100644
--- a/Go/Go.sublime-syntax
+++ b/Go/Go.sublime-syntax
@@ -250,6 +250,9 @@ contexts:
- match: (?i)sql\b
scope: meta.annotation.parameters.go constant.other.language-name.go
set: scope:source.go.embedded-backtick-string.sql#match-comment-magic-language-injection-inner
+ - match: (?i)t-?sql\b
+ scope: meta.annotation.parameters.go constant.other.language-name.go
+ set: scope:source.go.embedded-backtick-string.tsql#match-comment-magic-language-injection-inner
- match: (?i)xml\b
scope: meta.annotation.parameters.go constant.other.language-name.go
set: scope:source.go.embedded-backtick-string.xml#match-comment-magic-language-injection-inner
diff --git a/Go/tests/syntax_test_go.go b/Go/tests/syntax_test_go.go
index c272763cde..37d3b4126c 100644
--- a/Go/tests/syntax_test_go.go
+++ b/Go/tests/syntax_test_go.go
@@ -5883,7 +5883,7 @@ func lang_embedding() {
// ^ meta.string.go string.quoted.backtick.go punctuation.definition.string.begin.go
// ^ meta.string.go meta.embedded.go source.sql.embedded.go
update schema.table
- // ^^^^^^ meta.string.go meta.embedded.go source.sql.embedded.go keyword.other.DML.sql
+ // ^^^^^^ meta.string.go meta.embedded.go source.sql.embedded.go keyword.other.dml.sql
set
some_field = null
where
@@ -5907,6 +5907,17 @@ func lang_embedding() {
not_sql_string = `select not sql`
// ^^^^^^^^^^^^^^^^ meta.string.go string.quoted.backtick.go - source.sql
+ //language=t-sql
+ // <- comment.line.double-slash.go punctuation.definition.comment.go
+ //^^^^^^^^^^^^^^^ comment.line.double-slash.go
+ //^^^^^^^^ meta.annotation.identifier.go
+ // ^ meta.annotation keyword.operator.assignment.go
+ // ^^^^^ meta.annotation.parameters.go constant.other.language-name.go
+ sqlQuery = `
+ SELECT id
+ FROM ##global_temp_table;`
+ // ^^ punctuation.definition.variable
+
response := &http.Response{
StatusCode: http.StatusUnauthorized,
//language=json
diff --git a/PHP/Embeddings/SQL (for PHP Interpolated).sublime-syntax b/PHP/Embeddings/SQL (for PHP Interpolated).sublime-syntax
index b2467a53ef..d8ace3203c 100644
--- a/PHP/Embeddings/SQL (for PHP Interpolated).sublime-syntax
+++ b/PHP/Embeddings/SQL (for PHP Interpolated).sublime-syntax
@@ -1,6 +1,7 @@
%YAML 1.2
---
scope: source.sql.interpolated.php
+version: 2
hidden: true
extends: Packages/SQL/SQL.sublime-syntax
@@ -10,14 +11,24 @@ contexts:
- meta_prepend: true
- include: Packages/PHP/PHP Source.sublime-syntax#interpolations
+ main:
+ - meta_prepend: true
+ # prevent stray bracket highlighting
+ - match: \)
+ scope: punctuation.section.group.end.sql
+
+ single-identifier:
+ - meta_prepend: true
+ - meta_include_prototype: false
+ - include: Packages/PHP/PHP Source.sublime-syntax#interpolation
+
inside-like-single-quoted-string:
- meta_prepend: true
- - include: Packages/PHP/PHP Source.sublime-syntax#string-interpolations
+ - include: string-interpolation
- string-escape:
- # this context is included in anonymous string contexts
+ inside-single-quoted-string:
- meta_prepend: true
- - include: Packages/PHP/PHP Source.sublime-syntax#string-interpolations
+ - include: string-interpolation
string-interpolation:
# this context is included in anonymous string contexts
diff --git a/PHP/Embeddings/SQL (for PHP).sublime-syntax b/PHP/Embeddings/SQL (for PHP).sublime-syntax
index 361f780251..4cfcf3467c 100644
--- a/PHP/Embeddings/SQL (for PHP).sublime-syntax
+++ b/PHP/Embeddings/SQL (for PHP).sublime-syntax
@@ -1,6 +1,7 @@
%YAML 1.2
---
scope: source.sql.embedded.php
+version: 2
hidden: true
extends: Packages/SQL/SQL.sublime-syntax
@@ -11,6 +12,12 @@ contexts:
- include: php-single-quoted-strings
- include: php-string-single-quoted-escapes
+ main:
+ - meta_prepend: true
+ # prevent stray bracket highlighting
+ - match: \)
+ scope: punctuation.section.group.end.sql
+
php-string-single-quoted-escapes:
- match: \\[\\']
scope: constant.character.escape.php
diff --git a/PHP/PHP Source.sublime-syntax b/PHP/PHP Source.sublime-syntax
index dbf7e3ddca..9f6a09268c 100644
--- a/PHP/PHP Source.sublime-syntax
+++ b/PHP/PHP Source.sublime-syntax
@@ -1811,6 +1811,24 @@ contexts:
- match: (?=\${{identifier_start}})
push: interpolation-literal-variable
+ interpolation:
+ # PHP variable/expressions interpolated into foreign
+ # source code without clearing any string scopes.
+ #
+ # Prevents: "c:\{$foo}"
+ - match: \\\{
+ # Handles: "foo{$bar}baz"
+ - match: \{(?=\$)
+ scope: punctuation.section.interpolation.begin.php
+ set: interpolation-braced-expression
+ # Handles: "foo${bar}baz"
+ - match: \$\{
+ scope: punctuation.definition.variable.begin.php
+ set: interpolation-braced-variable
+ # Handles: $foo, $foo[0], $foo[$bar], $foo->bar
+ - match: (?=\${{identifier_start}})
+ set: interpolation-literal-variable
+
interpolation-braced-expression:
- meta_include_prototype: false
- meta_scope: meta.interpolation.php
diff --git a/PHP/tests/syntax_test_php.php b/PHP/tests/syntax_test_php.php
index 1c33997725..4be7bb5315 100644
--- a/PHP/tests/syntax_test_php.php
+++ b/PHP/tests/syntax_test_php.php
@@ -5191,21 +5191,21 @@ function testTypeCasts()
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.begin.php - meta.interpolation - string string
// ^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.double.php
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.end.php - meta.interpolation - string string
-// ^^^^^^ keyword.other.create.sql
+// ^^^^^^ keyword.other.ddl.sql
$sql = "
CREATE TABLE `version`...
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.double.php
-// ^^^^^^ keyword.other.create.sql
+// ^^^^^^ keyword.other.ddl.sql
";
// Do not highlight plain SQL indicator as SQL
$sql = "SELECT";
-// ^^^^^^ - keyword.other.DML
+// ^^^^^^ - keyword.other.dml
$sql = "
SELECT
-// ^^^^^^ keyword.other.DML
+// ^^^^^^ keyword.other.dml
*
FROM users
WHERE first_name = 'Eric'
@@ -5214,7 +5214,7 @@ function testTypeCasts()
$sql = "SELECT * FROM users WHERE first_name = 'Eric'";
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.begin.php - meta.interpolation - string string
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.double.php
-// ^ keyword.other.DML
+// ^ keyword.other.dml
// ^^^^^^ string.quoted.single.sql
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.end.php - meta.interpolation - string string
@@ -5222,26 +5222,38 @@ function testTypeCasts()
$sql = "SELECT * FROM users WHERE first_name = 'Eric";
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.begin.php - meta.interpolation - string string
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.double.php
-// ^ keyword.other.DML
+// ^ keyword.other.dml
// ^^^^^ string.quoted.single.sql
// ^ meta.string.php string.quoted.double.php punctuation.definition.string.end.php - meta.interpolation - string string
$sql = "
SELECT * FROM users WHERE first_name = 'Eric'
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.double.php
-// ^ keyword.other.DML
+// ^ keyword.other.dml
+// ^^^^^ keyword.other.dml.sql
// ^^^^^^ string.quoted.single.sql
";
// <- meta.string.php string.quoted.double.php punctuation.definition.string.end.php - meta.interpolation - string string
+$sql = "SELECT `$col` FROM 'my$table--name'";
+// ^^^^^^ meta.column-name.sql
+// ^ punctuation.definition.identifier.begin.sql
+// ^^^^ meta.interpolation.php variable.other.php
+// ^ punctuation.definition.identifier.end.sql
+// ^^^^ keyword.other.dml.sql
+// ^^^^^^^^^^^^^^^^ meta.table-name.sql
+// ^ punctuation.definition.identifier.begin.sql
+// ^^^^^^ meta.interpolation.php variable.other.php
+// ^ punctuation.definition.identifier.end.sql
+
$sql = "SELECT * FROM users where first_name = $user_name";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php - meta.interpolation
-// ^^^^^^^^^^ meta.string.php meta.interpolation.php variable.other.php - string
+// ^^^^^^^^^^ meta.string.php meta.interpolation.php variable.other.php - string.quoted.double
// ^ meta.string.php - meta.interpolation
$sql = "SELECT * FROM users where first_name = '$user_name'";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php - meta.interpolation
-// ^^^^^^^^^^ meta.string.php meta.interpolation.php variable.other.php - string
+// ^^^^^^^^^^ meta.string.php meta.interpolation.php variable.other.php - string.quoted
// ^ meta.string.php - meta.interpolation
$sql = "SELECT * FROM users where first_name = `$user_name`";
@@ -5270,22 +5282,12 @@ function testTypeCasts()
// ^ meta.string.php - meta.interpolation
// ^^^^^^^^^^ - meta.string
// ^ meta.string.php - meta.interpolation
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php
-// ^ meta.string.php - meta.interpolation
-// ^^^^^^^^^^^ - meta.string
-// ^ meta.string.php - meta.interpolation
-// ^ meta.string.php source.sql.embedded.php
-// ^ meta.string.php - meta.interpolation
-// ^^^^^ - meta.string
-// ^^^^^^^^^^ meta.string.php string.quoted.double.php - meta.interpolation
-// ^ string.quoted.double.php punctuation.definition.string.begin.php
-// ^^^^^^ keyword.other.DML.sql
-// ^ string.quoted.double.php punctuation.definition.string.end.php
-// ^ keyword.operator.concatenation.php
-// ^^^^ variable.other.php
-// ^ keyword.operator.concatenation.php
-// ^ string.quoted.double.php punctuation.definition.string.begin.php
-// ^^^^^^ variable.other.php
+// ^^^^^ meta.string.php source.sql.embedded.php - meta.interpolation
+// ^^^^^^ meta.string.php source.sql.embedded.php meta.table-name.sql meta.interpolation.php
+// ^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - meta.interpolation
+// ^ punctuation.section.group.begin.sql
+// ^^^^^^^^^^ meta.column-name.sql - variable
+// ^ keyword.operator.comparison.sql
// ^ string.quoted.double.php punctuation.definition.string.end.php
// ^ keyword.operator.concatenation.php
// ^^^^^ variable.other.php
@@ -5331,7 +5333,7 @@ function testTypeCasts()
$sql = 'SELECT * FROM users WHERE first_name = \'Eric\'';
// ^ meta.string.php string.quoted.single.php punctuation.definition.string.begin.php - meta.interpolation - string string
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.single.php
-// ^ keyword.other.DML
+// ^ keyword.other.dml
// ^^^^^^^^ meta.string.sql string.quoted.single.sql
// ^^ constant.character.escape.php
// ^^ constant.character.escape.php
@@ -5340,7 +5342,7 @@ function testTypeCasts()
$sql = '
SELECT * FROM users WHERE first_name = \'Eric\'
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.php source.sql.embedded.php - string.quoted.single.php
-// ^ keyword.other.DML
+// ^ keyword.other.dml
// ^^ constant.character.escape.php
';
// <- meta.string.php string.quoted.single.php punctuation.definition.string.end.php - meta.interpolation - string string
@@ -5360,7 +5362,7 @@ function testTypeCasts()
// ^^^^^ - meta.string
// ^^^^^^^^^^ meta.string.php string.quoted.single.php - meta.interpolation
// ^ string.quoted.single.php punctuation.definition.string.begin.php
-// ^^^^^^ keyword.other.DML.sql
+// ^^^^^^ keyword.other.dml.sql
// ^ string.quoted.single.php punctuation.definition.string.end.php
// ^ keyword.operator.concatenation.php
// ^^^^ variable.other.php
@@ -5557,7 +5559,7 @@ function testTypeCasts()
// ^^^ entity.name.tag.heredoc
SELECT * FROM users WHERE first_name = 'John' LIMIT $limit
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.embedded.sql source.sql.embedded.php
-// <- keyword.other.DML
+// <- keyword.other.dml
// ^ constant.other.wildcard.asterisk
// ^^^^^^ string.quoted.single
// ^^^^^^ variable.other.php
@@ -5574,7 +5576,7 @@ function testTypeCasts()
// ^^^ entity.name.tag.heredoc
SELECT * FROM users WHERE first_name = 'John'\n
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.embedded.sql source.sql.embedded.php
-// <- keyword.other.DML
+// <- keyword.other.dml
// ^ constant.other.wildcard.asterisk
// ^^^^^^ string.quoted.single
// ^^ - constant.character.escape.php
diff --git a/Python/tests/syntax_test_python_strings.py b/Python/tests/syntax_test_python_strings.py
index 4a2c02d3a2..5465042a6f 100644
--- a/Python/tests/syntax_test_python_strings.py
+++ b/Python/tests/syntax_test_python_strings.py
@@ -30,29 +30,29 @@
# ^^ invalid.deprecated.character.escape.python
conn.execute("SELECT * FROM foobar")
-# ^ meta.string.python keyword.other.DML.sql
+# ^ meta.string.python keyword.other.dml.sql
conn.execute('SELECT * FROM foobar')
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
conn.execute(U"SELECT * FROM foobar")
# ^ meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
# ^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql
# ^ meta.string.python string.quoted.double.python punctuation.definition.string.end.python
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
conn.execute(U'SELECT * FROM foobar')
# ^ meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
# ^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql
# ^ meta.string.python string.quoted.single.python punctuation.definition.string.end.python
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# In this example, the Python string is not raw, so \t is a python escape
conn.execute(u"SELECT * FROM foobar WHERE foo = '\t'")
# ^ storage.type.string.python
# ^ meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# ^ constant.character.escape.python
# ^ meta.string.python string.quoted.double.python punctuation.definition.string.end.python
@@ -60,44 +60,44 @@
# ^ meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
# ^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql
# ^ meta.string.python string.quoted.single.python punctuation.definition.string.end.python
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# In this example, the Python string is raw, so the \b should be a SQL escape
conn.execute(r"SELECT * FROM foobar WHERE baz = '\b")
-# ^ meta.string.python keyword.other.DML.sql
+# ^ meta.string.python keyword.other.dml.sql
# ^ constant.character.escape.sql
# This tests to ensure the Python placeholder will be highlighted even in a raw SQL string
conn.execute(r'SELECT * FROM foobar WHERE %s')
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# ^ constant.other.placeholder.python
conn.execute(r"SELECT * FROM foobar")
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
conn.execute(r'SELECT * FROM foobar')
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
conn.execute(r"""SELECT * FROM foobar WHERE %s and foo = '\t'""")
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# ^ constant.other.placeholder.python
# ^ constant.character.escape.sql
# Capital R prevents all syntax embedding
conn.execute(R'SELECT * FROM foobar')
-# ^ meta.string.python - keyword.other.DML.sql
+# ^ meta.string.python - keyword.other.dml.sql
conn.execute(R"SELECT * FROM foobar")
-# ^ - keyword.other.DML.sql
+# ^ - keyword.other.dml.sql
conn.execute(R"""SELECT * FROM foobar""")
-# ^ - keyword.other.DML.sql
+# ^ - keyword.other.dml.sql
conn.execute(r'''SELECT * FROM foobar''')
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
conn.execute(u"""SELECT * FROM foobar WHERE %s and foo = '\t'""")
-# ^ keyword.other.DML.sql
+# ^ keyword.other.dml.sql
# ^ constant.other.placeholder.python
# ^ constant.character.escape.python
@@ -211,7 +211,7 @@
EXISTS(
select 1)
ELSE NULL
- ) as result
+ END) as result
""" + test
# ^^^ meta.string.python string.quoted.double.block.python punctuation.definition.string.end.python
# ^ keyword.operator.arithmetic.python
@@ -229,7 +229,7 @@
EXISTS(
select 1)
ELSE NULL
- ) as result
+ END) as result
"""
query = \
@@ -243,7 +243,7 @@
EXISTS(
select 1)
ELSE NULL
- ) as result
+ END) as result
'''
query = """
@@ -914,6 +914,9 @@
COMMIT;"
# ^^^^^^ meta.string.python source.sql - string
+sql = "DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 13;"
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql - string.quoted
+
sql = Ur"SELECT `name` FROM `users` \
WHERE `password` LIKE 'abc'"
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.python source.sql - string.quoted.double
diff --git a/Rails/SQL (Rails).sublime-syntax b/Rails/SQL (Rails).sublime-syntax
index 5a10f58090..5a49301d62 100644
--- a/Rails/SQL (Rails).sublime-syntax
+++ b/Rails/SQL (Rails).sublime-syntax
@@ -2,6 +2,7 @@
---
name: SQL (Rails)
scope: source.sql.rails
+version: 2
extends: Packages/SQL/SQL.sublime-syntax
diff --git a/Ruby/Embeddings/SQL (for Ruby).sublime-syntax b/Ruby/Embeddings/SQL (for Ruby).sublime-syntax
index dac679e014..a81d06ecc2 100644
--- a/Ruby/Embeddings/SQL (for Ruby).sublime-syntax
+++ b/Ruby/Embeddings/SQL (for Ruby).sublime-syntax
@@ -1,7 +1,7 @@
%YAML 1.2
---
scope: source.sql.embedded.ruby
-# version: 2
+version: 2
hidden: true
extends: Packages/SQL/SQL.sublime-syntax
diff --git a/SQL/Cassandra.sublime-syntax b/SQL/Cassandra.sublime-syntax
new file mode 100644
index 0000000000..01aa50387e
--- /dev/null
+++ b/SQL/Cassandra.sublime-syntax
@@ -0,0 +1,242 @@
+%YAML 1.2
+---
+# https://cassandra.apache.org/doc/latest/cassandra/cql/
+name: Cassandra Query Language
+scope: source.sql.cql
+version: 2
+
+extends: Packages/SQL/SQL (basic).sublime-syntax
+
+file_extensions:
+ - cql
+
+variables:
+
+ ddl_target_function: |-
+ (?xi: function )
+
+ ddl_target_other: |-
+ (?xi: keyspace | type | user | (?: materialized \s+ )? view )
+
+ simple_types: |-
+ (?xi:
+ ASCII | BIGINT | BLOB | BOOLEAN | COUNTER | DATE | DECIMAL | DOUBLE
+ | DURATION | FLOAT | INET | INT | SMALLINT | TEXT | TIME | TIMESTAMP
+ | TIMEUUID | TINYINT | UUID | VARCHAR | VARINT )
+
+ types_with_optional_number: (?!)
+
+contexts:
+
+###[ DDL CREATE STATEMENTS ]###################################################
+
+ create-target:
+ - meta_prepend: true
+ - include: create-type
+
+ create-type:
+ - match: \b(?i:type)\b
+ scope: keyword.other.ddl.cql
+ push:
+ - create-type-args
+ - maybe-column-declaration-list
+ - expect-type-creation-name
+ - create-type-condition
+
+ create-type-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-type-args:
+ - meta_scope: meta.type.sql
+ - include: create-common-args
+
+ create-common-args:
+ - meta_prepend: true
+ - match: \b(?i:clustering)\b
+ scope: keyword.other.cql
+ - match: \b(?i:with)\b
+ scope: keyword.other.cql
+
+###[ DML STATEMENTS ]##########################################################
+
+ dml-statements:
+ - meta_prepend: true
+ - match: \b(?i:(select)\s+(json))\b
+ captures:
+ 1: keyword.other.dml.sql
+ 2: storage.modifier.cql
+ - match: \b(?i:allow\s+filtering)\b
+ scope: keyword.other.dml.cql
+ - match: \b(?i:copy)\b
+ scope: keyword.other.dml.cql
+ push:
+ - dml-copy-from
+ - maybe-group
+ - expect-table-name
+
+ dml-copy-from:
+ - match: \b(?i:from)\b
+ scope: keyword.other.cql
+ pop: 1
+ - include: else-pop
+
+ join-expressions: []
+
+###[ OTHER STATEMENTS ]########################################################
+
+ other-statements:
+ - meta_prepend: true
+ - match: \b(?i:use)\b
+ scope: keyword.context.sql
+ push: expect-database-name
+ - match: \b(?i:source)\b
+ scope: keyword.other.cql
+
+###[ EXPRESSIONS ]#############################################################
+
+ expressions:
+ - meta_append: true
+ - include: arrays
+ - include: dicts-or-sets
+ - match: \b(?i:limit)\b
+ scope: keyword.other.dml.cql
+ - match: \b((?i:with))\s+(\w+)?
+ captures:
+ 1: keyword.other.cql
+ 2: string.unquoted.cql
+ - match: \b(?i:primary\s+key)\b
+ scope: storage.modifier.cql
+ - match: \b(?i:using\s+ttl)\b
+ scope: keyword.other.cql
+
+ built-in-scalar-function-calls:
+ - meta_append: true
+ - match: \b(?:token|uuid|now|toJson|TTL|WRITETIME|KEYS|ENTRIES|FULL)(?=\s*\()
+ scope: support.function.scalar.cql
+ push: function-call-arguments
+
+ arrays:
+ - match: \[
+ scope: punctuation.section.brackets.begin.cql
+ push: inside-array
+
+ inside-array:
+ - meta_scope: meta.brackets.cql
+ - match: \]
+ scope: punctuation.section.brackets.end.cql
+ pop: 1
+ - include: expressions
+
+ dicts-or-sets:
+ - match: \{
+ scope: punctuation.section.braces.begin.cql
+ push: inside-dict-or-set
+
+ inside-dict-or-set:
+ - meta_scope: meta.braces.cql
+ - match: \}
+ scope: punctuation.section.braces.end.cql
+ pop: 1
+ - match: ':'
+ scope: punctuation.separator.key-value.cql
+ - include: expressions
+ - match: '{{simple_identifier}}'
+ scope: meta.mapping.key.cql string.unquoted.cql
+
+###[ COLUMN EXPRESSIONS ]######################################################
+
+ inside-column-declaration-list:
+ - meta_scope: meta.group.table-columns.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - match: \b(?i:(primary\s+key))\s*(\()
+ captures:
+ 1: storage.modifier.cql
+ 2: meta.group.partition-key.cql punctuation.section.group.begin.cql
+ push: inside-partition-key
+ - match: \b(?i:primary\s+key)\b
+ scope: storage.modifier.cql
+ - include: expressions
+ - include: expect-column-declarations
+
+ inside-partition-key:
+ - meta_content_scope: meta.group.partition-key.cql
+ - match: \)
+ scope: meta.group.partition-key.cql punctuation.section.group.end.cql
+ pop: 1
+ - match: \(
+ scope: punctuation.section.group.begin.cql
+ push: inside-partition-key-group
+ - match: ','
+ scope: punctuation.separator.sequence.cql
+ set: inside-group
+ - include: expect-column-names
+
+ inside-partition-key-group:
+ - match: \)
+ scope: punctuation.section.group.end.cql
+ pop: 1
+ - match: ','
+ scope: punctuation.separator.sequence.cql
+ - include: expect-column-names
+
+###[ TYPES ]###################################################################
+
+ built-in-type:
+ - meta_prepend: true
+ # https://cassandra.apache.org/doc/latest/cassandra/cql/types.html#collections
+ - match: \b(?i:frozen|list|map|set|tuple)\b
+ scope: storage.type.cql
+ set: maybe-generic
+
+ maybe-generic:
+ - match: <
+ scope: punctuation.definition.generic.begin.cql
+ set:
+ - inside-generic
+ - expect-generic-type
+ - include: else-pop
+
+ inside-generic:
+ - meta_scope: meta.generic.cql
+ - match: \>
+ scope: punctuation.definition.generic.end.cql
+ pop: 1
+ - match: ','
+ scope: punctuation.separator.sequence.cql
+ push: expect-generic-type
+
+ expect-generic-type:
+ - match: (?=[,>])
+ pop: 1
+ - include: expect-type
+
+###[ LITERALS ]################################################################
+
+ constants:
+ - meta_prepend: true
+ - include: booleans
+
+ literals-and-variables:
+ - meta_prepend: true
+ - include: variables
+
+ numbers:
+ - meta_prepend: true
+ - match: \h{8}(?:-\h{4}){3}-\h{12}
+ scope: constant.numeric.uuid.cql
+
+ variables:
+ - match: (:){{simple_identifier}}
+ scope: variable.other.constant.cql
+ captures:
+ 1: punctuation.definition.variable.cql
+
+###[ OPERATORS ]###############################################################
+
+ logical-operators:
+ - meta_append: true
+ - match: \b(?i:contains(?:\s+key)?)\b
+ scope: keyword.operator.logical.cql
diff --git a/SQL/Indentation Rules - Comments.tmPreferences b/SQL/Indentation Rules - Comments.tmPreferences
new file mode 100644
index 0000000000..e018720e72
--- /dev/null
+++ b/SQL/Indentation Rules - Comments.tmPreferences
@@ -0,0 +1,12 @@
+
+
+
+ scope
+ source.sql comment
+ settings
+
+ preserveIndent
+
+
+
+
diff --git a/SQL/Indentation Rules.tmPreferences b/SQL/Indentation Rules.tmPreferences
index 8bc06e9e1e..941f81f112 100644
--- a/SQL/Indentation Rules.tmPreferences
+++ b/SQL/Indentation Rules.tmPreferences
@@ -2,13 +2,27 @@
scope
- source.sql
+ source.sql - string - comment
settings
decreaseIndentPattern
- \)(?!=.*\()
+ (?xi)
+ \)(?!=.*\()
+ |^\s*end\b
+
increaseIndentPattern
- ^\s*(create|grant|insert|delete|update)\b|\((?!.*\))
+ (?xi)
+ ^\s*
+ (?:
+ (?:create|grant|delete|update|begin)\b
+ #| select\s*$
+ )
+ |\((?!.*\))
+
+ unIndentedLinePattern
+ (?xi)
+ ^go$
+
diff --git a/SQL/Indexed Symbol List.tmPreferences b/SQL/Indexed Symbol List.tmPreferences
new file mode 100644
index 0000000000..7421686520
--- /dev/null
+++ b/SQL/Indexed Symbol List.tmPreferences
@@ -0,0 +1,12 @@
+
+
+
+ scope
+ source.sql entity.name.struct
+ settings
+
+ showInIndexedSymbolList
+ 1
+
+
+
diff --git a/SQL/MySQL.sublime-syntax b/SQL/MySQL.sublime-syntax
new file mode 100644
index 0000000000..3bd6ebcbda
--- /dev/null
+++ b/SQL/MySQL.sublime-syntax
@@ -0,0 +1,1694 @@
+%YAML 1.2
+---
+name: MySQL
+scope: source.sql.mysql
+version: 2
+
+extends: Packages/SQL/SQL (basic).sublime-syntax
+
+variables:
+ additional_toplevel_reserved: |-
+ (?xi: {{conditional_keywords}} | {{flow_keywords}} | {{loop_keywords}}
+ | begin | end | rename | show )
+
+ conditional_keywords: |-
+ (?xi: if | end\s+if | else(?:if)? | then )
+
+ flow_keywords: |-
+ (?xi: continue | exit | return )
+
+ loop_keywords: |-
+ (?xi: loop | end\s+(?: loop | repeat | while ) | repeat | while )
+
+ other_keywords: |-
+ (?xi: close | cursor | declare | deallocate | delimiter | execute | fetch
+ | for | found | open | prepare | with )
+
+ function_parameter_modifier: |-
+ (?xi: in\s*out | in | out )
+
+ database_parameters: |-
+ (?xi: (?:default\s+)? (?: char(?:acter\s+)?set | collate ) )
+
+ partition_parameters: |-
+ (?xi: (?:storage\s+)?engine | (?:data|index)\s+directory | max_rows | min_rows | nodegroup )
+
+ table_parameters: |-
+ (?xi: (?:storage\s+)?engine | (?:default\s+)?(?: char(?:acter\s+)?set | collate )
+ | auto_increment | avg_row_length | checksum | connection | data\s+directory
+ | delay_key_write | encrypted | encryption_key_id | ietf_quotes | index\s+directory
+ | insert_method | key_block_size | max_rows | min_rows | pack_keys | page_checksum
+ | page_compressed | page_compression_level | password | row_format | sequence
+ | stats_auto_recalc | stats_persistent | stats_sample_pages | transactional )
+ table_row_formats: |-
+ (?xi: dynamic | fixed | compressed | redundant | compact | page )
+
+ # https://mariadb.com/kb/en/data-types
+ simple_types: |-
+ (?xi: boolean | bool | uuid | year )
+
+ types_with_optional_number: |-
+ (?xi:
+ # numeric data types
+ (?: big | medium | middle | small | tiny ) int
+ | bit(?: \s+ varying )?
+ | date(?: time )?
+ | dec(?: imal )?
+ | double(?: \s+ precision )?
+ | fixed
+ | float[48]?
+ | int(?: [12348] | eger )?
+ | number
+ | numeric
+ | real
+ | (?: local )?time(?: stamp )?
+ # string data types
+ | (?: long | medium | tiny )? (?: blob | text )
+ | binary (?: \s+ varying )?
+ | char \s+ byte
+ | (?: national \s+ )? char(?: acter )? (?: \s+ varying )?
+ | inet[46]
+ | long(?: \s+ varchar )?
+ | var(?: binary | char (?: acter )? )
+ )
+
+ time_units: |-
+ (?xi: year(?: _month )? | day(?: _hour | _minute | _second | _microsecond )?
+ | hour(?: _minute | _second | _microsecond )? | minute(?: _second | _microsecond )?
+ | second(?: _microsecond )? | quarter | month | week )
+
+ builtin_constants: |-
+ (?xi: all | default | maxvalue
+ # index algorithm/lock values
+ | inplace | copy | nocopy | instant | exclusive | shared
+ | system\s+versioning )
+
+ builtin_user_functions: |-
+ (?xi: (?: current | session | system )_(?: role | user ))
+
+contexts:
+ sql:
+ - meta_append: true
+ - include: regexps
+
+ statements:
+ - meta_prepend: true
+ - include: rename-statements
+ - include: show-statements
+
+###[ COMMENTS ]################################################################
+
+ comments:
+ - meta_append: true
+ - include: number-sign-comments
+
+ double-dash-comments:
+ - match: '--(?=\s)'
+ scope: punctuation.definition.comment.sql
+ push: inside-double-dash-comment
+
+ number-sign-comments:
+ - match: '#'
+ scope: punctuation.definition.comment.sql
+ push: inside-number-sign-comment
+
+ inside-number-sign-comment:
+ - meta_include_prototype: false
+ - meta_scope: comment.line.number-sign.sql
+ - match: \n
+ pop: 1
+
+###[ DDL CREATE STATEMENTS ]###################################################
+
+ create-statements:
+ - meta_prepend: true
+ - match: \b(?i:create\s+or\s+replace)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - create-meta
+ - create-target
+
+ create-target:
+ - meta_prepend: true
+ - include: algorithms
+ - include: definers
+ - include: create-database
+ - include: create-event
+ - include: create-role
+ - include: create-user
+
+ create-database:
+ # https://mariadb.com/kb/en/create-database
+ - match: \b(?i:database|schema)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-database-args
+ - expect-database-creation-name
+ - create-database-condition
+
+ create-database-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-database-args:
+ - meta_scope: meta.database.sql
+ - match: \b{{database_parameters}}\b
+ scope: variable.parameter.database.sql
+ - include: assignment-operators-constants
+ - include: comment-keywords
+ - include: strings
+ - include: else-pop
+
+ create-event:
+ # https://mariadb.com/kb/en/create-event
+ - match: \b(?i:event)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-event-args
+ - expect-event-creation-name
+ - create-event-condition
+
+ create-event-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-event-args:
+ - meta_scope: meta.event.sql
+ - include: event-options
+ - include: pop-on-top-level-reserved-word
+
+ create-index-args:
+ # https://mariadb.com/kb/en/create-index
+ - meta_prepend: true
+ - include: index-algorithm-args
+ - include: index-clustering-args
+ - include: index-lock-args
+ - include: index-parser-args
+ - include: index-type-args
+ - include: index-wait-args
+ - include: index-other-args
+ - include: comment-keywords
+
+ create-role:
+ # https://mariadb.com/kb/en/create-role
+ - match: \b(?i:role)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-role-args
+ - expect-user-name-declaration
+ - create-role-condition
+
+ create-role-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-role-args:
+ - meta_scope: meta.user.sql
+ - include: maybe-with-admin-user
+
+ create-table-args:
+ # https://mariadb.com/kb/en/create-table
+ - meta_prepend: true
+ - include: partition-declaration-lists
+ - include: partition-options
+ - include: table-options
+
+ create-user:
+ # https://mariadb.com/kb/en/create-user
+ - match: \b(?i:user)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-user-args
+ - create-user-name-list
+ - user-identification
+ - expect-user-name-declaration
+ - create-user-condition
+
+ create-user-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-user-name-list:
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+ push:
+ - user-identification
+ - expect-user-name-declaration
+ - include: else-pop
+
+ create-user-args:
+ - meta_scope: meta.user.sql
+ - include: user-options
+
+ create-other-args:
+ - meta_prepend: true
+ - match: (?=\()
+ push: column-declaration-list
+
+###[ DDL DROP STATEMENTS ]#####################################################
+
+ drop-target:
+ - meta_prepend: true
+ - include: algorithms
+ - include: drop-database
+ - include: drop-event
+ - include: drop-user
+
+ drop-database:
+ # https://mariadb.com/kb/en/drop-database
+ - match: \b(?i:database|schema)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-database-args
+ - expect-database-name
+ - drop-database-condition
+
+ drop-database-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-database-args:
+ - meta_include_prototype: false
+ - meta_scope: meta.database.sql
+ - include: immediately-pop
+
+ drop-event:
+ # https://mariadb.com/kb/en/drop-event
+ - match: \b(?i:event)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-event-args
+ - expect-event-name
+ - drop-event-condition
+
+ drop-event-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-event-args:
+ - meta_include_prototype: false
+ - meta_scope: meta.event.sql
+ - include: immediately-pop
+
+ drop-index-args:
+ - meta_prepend: true
+ - include: index-wait-args
+
+ drop-user:
+ # https://mariadb.com/kb/en/drop-role
+ # https://mariadb.com/kb/en/drop-user
+ - match: \b(?i:role|user)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-user-args
+ - expect-user-name
+ - drop-user-condition
+
+ drop-user-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-user-args:
+ - meta_scope: meta.user.sql
+ - include: user-name-list
+
+###[ DDL ALTER STATEMENTS ]####################################################
+
+ alter-target:
+ - meta_prepend: true
+ - include: algorithms
+ - include: definers
+ - include: alter-database
+ - include: alter-event
+ - include: alter-user
+
+###[ DDL ALTER COLUMNS STATEMENTS ]############################################
+
+ alter-columns:
+ - meta_prepend: true
+ - match: \b(?i:(change)\s+(column))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ push:
+ - expect-type
+ - expect-column-name-declaration
+ - expect-column-name
+
+###[ DDL ALTER DATABASE STATEMENTS ]###########################################
+
+ alter-database:
+ # https://mariadb.com/kb/en/alter-database
+ - match: \b(?i:database|schema)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - alter-database-args
+ - expect-database-name
+ - alter-database-condition
+
+ alter-database-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-database-args:
+ - meta_scope: meta.database.sql
+ - match: \b(?i:(upgrade)(?:\s+(data\s+directory\s+name))?)\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ pop: 1
+ - include: create-database-args
+
+###[ DDL ALTER EVENT STATEMENTS ]##############################################
+
+ alter-event:
+ # https://mariadb.com/kb/en/alter-event
+ - match: \b(?i:event)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - alter-event-args
+ - expect-event-name
+ - alter-event-condition
+
+ alter-event-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-event-args:
+ - meta_scope: meta.event.sql
+ - include: event-options
+ - include: pop-on-top-level-reserved-word
+
+###[ DDL ALTER TABLE STATEMENTS ]##############################################
+
+ alter-table:
+ - meta_prepend: true
+ - match: \b(?i:online|ignore)\b
+ scope: keyword.other.ddl.sql
+
+ alter-table-args:
+ - match: \b(?i:add)\b
+ scope: keyword.other.ddl.sql
+ push: alter-table-add-target
+ - match: \b(?i:change)\b
+ scope: keyword.other.ddl.sql
+ push: alter-table-change-target
+ - match: \b(?i:drop)\b
+ scope: keyword.other.ddl.sql
+ push: alter-table-drop-target
+ - match: \b(?i:modify)\b
+ scope: keyword.other.ddl.sql
+ push: alter-table-modify-target
+ - match: \b(?i:rename)\b
+ scope: keyword.other.ddl.sql
+ push: alter-table-rename-target
+ # drop args
+ - match: \b(?i:cascade|restrict)\b
+ scope: keyword.other.ddl.sql
+ # partition commands
+ - match: \b(?i:check)\b
+ scope: keyword.other.sql
+ # table options
+ - include: index-wait-args
+ - include: partition-options
+ - include: table-options
+ # expressions
+ - include: pop-on-top-level-reserved-word
+ - include: literals-and-variables
+ - include: comma-separators
+ - include: operators
+
+ alter-table-add-target:
+ - include: system-versioning
+ - include: alter-table-add-index
+ - include: alter-table-add-partition
+ - include: alter-table-add-period
+ - include: alter-table-add-column # must be the last one
+
+ alter-table-add-column:
+ - match: (?=\S)
+ set:
+ - maybe-column-position
+ - expect-column-declaration
+ - maybe-condition
+ - maybe-column
+
+ alter-table-add-index:
+ - match: \b(?i:constraint)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - maybe-check
+ - expect-constraint-name
+ - match: \b(?i:(primary)\s+(key))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set: alter-table-add-index-args
+ - match: \b(?i:(?:(foreign|fulltext|spatial|unique)\s+)?(index|key))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - alter-table-add-index-args
+ - expect-index-name
+ - maybe-condition
+
+ alter-table-add-index-args:
+ - include: column-name-lists
+ - include: comment-keywords
+ - include: index-algorithm-args
+ - include: index-clustering-args
+ - include: index-lock-args
+ - include: index-parser-args
+ - include: index-type-args
+ - include: index-other-args
+ - include: literals-and-variables
+ - include: operators
+ - include: else-pop
+
+ alter-table-add-partition:
+ - match: \b(?i:partition)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - maybe-partition-declaration-list
+ - maybe-condition
+
+ alter-table-add-period:
+ - match: \b(?i:(period)\s+(for)\s+(system_time))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ 3: keyword.other.ddl.sql
+ set: maybe-column-name-list
+
+ alter-table-change-target:
+ - include: alter-table-change-column
+
+ alter-table-change-column:
+ - match: (?=\S)
+ set:
+ - after-type
+ - expect-type
+ - expect-column-name-declaration
+ - expect-column-name
+ - maybe-condition
+ - maybe-column
+
+ alter-table-drop-target:
+ - include: system-versioning
+ - include: alter-table-drop-constraint
+ - include: alter-table-drop-index
+ - include: alter-table-drop-partition
+ - include: alter-table-drop-column # must be the last one
+
+ alter-table-drop-column:
+ - match: (?=\S)
+ set:
+ - expect-column-name
+ - maybe-condition
+ - maybe-column
+
+ alter-table-drop-constraint:
+ - match: \b(?i:constraint)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-constraint-name
+ - maybe-condition
+
+ alter-table-drop-index:
+ - match: \b(?i:primary\s+key)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+ - match: \b(?i:index|(?:foreign\s+)?key)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-index-name
+ - maybe-condition
+
+ alter-table-drop-partition:
+ - match: \b(?i:partition)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-partition-name
+ - maybe-condition
+
+ alter-table-modify-target:
+ - include: alter-table-modify-column
+
+ alter-table-modify-column:
+ - match: (?=\S)
+ set:
+ - after-type
+ - expect-type
+ - expect-column-name-declaration
+ - maybe-condition
+ - maybe-column
+
+ alter-table-rename-target:
+ - include: alter-table-rename-column
+ - include: alter-table-rename-index
+ - include: alter-table-rename-table # must be the last one
+
+ alter-table-rename-column:
+ - match: \b(?i:column)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-column-name
+ - maybe-to
+ - expect-column-name
+
+ alter-table-rename-index:
+ - match: \b(?i:index|key)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-index-name
+ - maybe-to
+ - expect-index-name
+
+ alter-table-rename-table:
+ - match: (?=\S)
+ set:
+ - expect-table-name
+ - maybe-to
+
+###[ DDL ALTER USER STATEMENTS ]###############################################
+
+ alter-user:
+ # https://mariadb.com/kb/en/alter-user
+ - match: \b(?i:user)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - alter-user-args
+ - expect-user-identification-list
+ - user-identification
+ - expect-user-name
+ - alter-user-condition
+
+ alter-user-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-user-args:
+ - meta_scope: meta.user.sql
+ - include: user-options
+
+###[ DML STATEMENTS ]##########################################################
+
+ dml-statements:
+ - meta_append: true
+ - include: index-hint-lists
+ - match: \b(?i:insert(\s+(?:ignore\s+)?into)?)\b
+ scope: keyword.other.dml.sql
+ push: expect-table-name
+ - match: \b(?i:limit)\b
+ scope: keyword.other.dml.sql
+ - match: \b(?i:on\s+duplicate\s+key)\b
+ scope: keyword.other.dml.sql
+
+ join-expressions:
+ # https://mariadb.com/kb/en/join-syntax
+ - match: \b(?i:(?:(?:cross|inner|(?:natural\s+)?(?:left|right)(?:\s+outer)?)\s+|straight_)?join)\b
+ scope: keyword.other.dml.sql
+ push:
+ - join-condition
+ - table-name-or-subquery
+
+ join-condition:
+ - meta_prepend: true
+ - match: \b(?i:using)\b
+ scope: keyword.other.dml.sql
+ set: maybe-column-name-list
+
+###[ DML SET STATEMENTS ]######################################################
+
+ set-target:
+ - meta_prepend: true
+ - include: set-password
+ - include: set-role
+
+ set-password:
+ # https://mariadb.com/kb/en/set-password
+ - match: \b(?i:password)\b
+ scope: keyword.other.dml.sql
+ set:
+ - set-other-assignment
+ - maybe-for-user
+
+ set-role:
+ # https://mariadb.com/kb/en/set-role
+ # https://mariadb.com/kb/en/set-default-role
+ - match: \b(?i:(?:(default)\s+)?(role))\b
+ captures:
+ 1: keyword.other.dml.sql
+ 2: keyword.other.dml.sql
+ set:
+ - maybe-for-user
+ - set-role-name
+
+ set-role-name:
+ - include: none-constant
+ - include: expect-user-name
+
+ set-other-assignment:
+ - match: =
+ scope: keyword.operator.assignment.sql
+ set: set-other-value
+ - include: else-pop
+
+ set-other-value:
+ - include: expressions
+ - include: pop-on-top-level-reserved-word
+
+###[ GRANT STATEMENTS ]########################################################
+
+ grant-statements:
+ # https://mariadb.com/kb/en/grant
+ - match: \b(?i:grant)\b
+ scope: keyword.other.authorization.sql
+ push:
+ - grant-meta
+ - grant-options
+ - grant-to-user
+ - grant-target
+
+ grant-target:
+ # grant proxy on name to user
+ - match: \b(?i:proxy)\b
+ scope: keyword.other.ddl.sql
+ set: grant-on-user
+ # grant role name to
+ - match: (?=\S+\s+(?i:to)\b)
+ set: expect-user-name
+ # grant operation on
+ - match: (?=\S)
+ set: grant-operations
+
+ grant-operations:
+ - match: (?=[;)]|\b(?i:grant|to|with)\b)
+ pop: 1
+ - include: on-privilidge-level
+ - include: comma-separators
+ - include: user-privileges
+
+ grant-on-user:
+ - match: \b(?i:on)\b
+ scope: keyword.context.sql
+ - include: expect-user-name
+
+ grant-to-user:
+ - match: \b(?i:to)\b
+ scope: keyword.context.sql
+ - include: expect-user-identification-list
+
+ grant-options:
+ - include: user-grant-privileges
+ - include: user-resource-options
+ - include: else-pop
+
+###[ RENAME STATEMENTS ]#######################################################
+
+ rename-statements:
+ # https://mariadb.com/kb/en/rename-user
+ - match: \b(?i:rename)\b
+ scope: keyword.other.authorization.sql
+ push:
+ - rename-meta
+ - rename-target
+
+ rename-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.rename.sql
+ - include: immediately-pop
+
+ rename-target:
+ - match: \b(?i:user)\b
+ scope: keyword.other.authorization.sql
+ set:
+ - rename-user
+ - expect-user-name
+ - include: else-pop
+
+ rename-user:
+ - match: \b(?i:to)\b
+ scope: keyword.context.sql
+ push: expect-user-name
+ - include: user-name-list
+
+###[ REVOKE STATEMENTS ]#######################################################
+
+ revoke-statements:
+ # https://mariadb.com/kb/en/revoke
+ - match: \b(?i:revoke)\b
+ scope: keyword.other.authorization.sql
+ push:
+ - revoke-meta
+ - revoke-options
+ - revoke-privileges
+
+ revoke-privileges:
+ - match: (?=[;)]|\b(?i:for|from)\b)
+ pop: 1
+ - include: on-privilidge-level
+ - include: comma-separators
+ - include: user-privileges
+
+ revoke-options:
+ - match: \b(?i:for|from)\b
+ scope: keyword.context.sql
+ push:
+ - user-name-list
+ - expect-user-name
+ - include: else-pop
+
+###[ SHOW STATEMENTS ]#########################################################
+
+ show-statements:
+ - match: \b(?i:show|describe)\b
+ scope: keyword.other.dml.sql
+ push:
+ - show-meta
+ - show-target
+ - match: \b(?i:explain(?:\s+analyze)?)\b
+ scope: keyword.other.dml.sql
+ push: explain-parameters
+
+ show-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.show.sql
+ - include: immediately-pop
+
+ show-target:
+ - include: show-create
+ - include: show-grants
+ - include: show-columns
+ - include: else-pop
+
+ show-create:
+ - match: \b(?i:create)\b
+ scope: keyword.other.ddl.sql
+ set: show-create-target
+
+ show-create-target:
+ - include: show-create-event
+ - include: show-create-user
+ - include: show-create-other
+ - include: else-pop
+
+ show-create-event:
+ # https://mariadb.com/kb/en/show-create-event
+ - match: \b(?i:event)\b
+ scope: keyword.other.ddl.sql
+ set: expect-event-name
+
+ show-create-user:
+ # https://mariadb.com/kb/en/show-create-user
+ - match: \b(?i:user)\b
+ scope: keyword.other.ddl.sql
+ set: expect-user-name
+
+ show-create-other:
+ - match: '{{simple_identifier}}'
+ scope: keyword.other.ddl.sql
+ set: expect-other-name
+
+ show-grants:
+ # https://mariadb.com/kb/en/show-grants
+ - match: \b(?i:grants)\b
+ scope: keyword.other.dml.sql
+ set: maybe-for-user
+
+ show-columns:
+ - match: \b(?i:full|extended)\b
+ scope: keyword.other.mysql
+ - match: \b(?i:columns|fields)\b
+ scope: keyword.other.mysql
+ - match: \b(?i:from|in)\b
+ scope: keyword.other.mysql
+ set: expect-table-name
+
+ explain-parameters:
+ - match: \b(?i:format)\b
+ scope: variable.parameter.explain.sql
+ - include: assignment-operators-constants
+ - match: \b(?i:into)\b
+ scope: keyword.other.dml.sql
+ push: expect-table-name
+ - match: \b(?i:for\s+schema)\b
+ scope: keyword.other.dml.sql
+ push: expect-other-name
+ - include: else-pop
+
+###[ OTHER STATEMENTS ]########################################################
+
+ other-statements:
+ - match: \b{{conditional_keywords}}\b
+ scope: keyword.control.conditional.sql
+ - match: \b{{loop_keywords}}\b
+ scope: keyword.control.loop.sql
+ - match: \b(?i:begin(\s+work)?|start\s+transaction|commit(\s+work)?|rollback(\s+work)?)\b
+ scope: keyword.other.luw.sql
+ - match: \b(?i:end)\b
+ scope: keyword.control.flow.end.sql
+ - match: \b(?i:continue)\b
+ scope: keyword.control.flow.continue.sql
+ - match: \b(?i:exit)\b
+ scope: keyword.control.flow.exit.sql
+ - match: \b(?i:return)\b
+ scope: keyword.control.flow.return.sql
+ - match: \b(?i:(?:un)?lock\s+tables?)\b
+ scope: keyword.context.resource.mysql
+ push:
+ - expect-lock-type
+ - expect-table-name
+
+ expect-lock-type:
+ - match: \b(?i:read|write)\b
+ scope: constant.language.lock-type.mysql
+ - match: ','
+ scope: punctuation.separator.sequence.mysql
+ set:
+ - expect-lock-type
+ - expect-table-name
+ - include: else-pop
+
+###[ EXPRESSIONS ]#############################################################
+
+ expressions:
+ - meta_prepend: true
+ - match: \b{{other_keywords}}\b
+ scope: keyword.other.sql
+ - match: \b(?i:concatenate|convert|lower|substring|translate|trim|upper)\b
+ scope: support.function.string.sql
+ - match: \b(?i:using)\b
+ scope: keyword.other.dml.sql
+ - include: like-expressions
+
+ assignment-operators-constants:
+ - include: assignment-operators
+ - match: \b(?i:utf8|utf8mb3|tree|traditional|json)\b
+ scope: string.unquoted.mysql
+
+###[ ALGORITHM EXPRESSIONS ]###################################################
+
+ algorithms:
+ - match: \b(?i:algorithm)\b
+ scope: keyword.other.mysql
+ push: algorithm-assignment
+
+ algorithm-assignment:
+ - match: =
+ scope: keyword.operator.assignment.sql
+ set: algorithm-value
+ - include: else-pop
+
+ algorithm-value:
+ - match: \b(?i:merge|temptable|undefined)\b
+ scope: constant.language.sql
+ pop: 1
+ - include: else-pop
+
+ definers:
+ - match: \b(?i:definer)\b
+ scope: variable.parameter.definer.sql
+ push: maybe-user-assignment
+
+###[ COLUMN EXPRESSIONS ]######################################################
+
+ inside-column-declaration-list:
+ - meta_prepend: true
+ - match: \b(?i:auto_increment)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:(comment\s+on\s+(table|column|aggregate|constraint|database|domain|function|index|operator|rule|schema|sequence|trigger|type|view))\s+.*?\s+(is))
+ scope: keyword.other.object-comments.sql
+
+###[ EVENT EXPRESSIONS ]#######################################################
+
+ event-options:
+ - match: \b(?i:do)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+ - include: comment-keywords
+ - include: event-schedule-args
+ - include: event-enable-args
+ - include: event-completion-args
+
+ event-completion-args:
+ - match: \b(?i:(on)\s+(completion))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ - match: \b(?i:preserve)\b
+ scope: constant.language.sql
+
+ event-enable-args:
+ - match: \b(?i:(on)\s+(slave))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ - match: \b(?i:enable|disable)\b
+ scope: keyword.other.ddl.sql
+
+ event-schedule-args:
+ - match: \b(?i:(on)\s+(schedule))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ - match: \b(?i:starts|ends)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:at)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:every)\b
+ scope: keyword.other.ddl.sql
+ - include: intervals
+ - include: expressions
+
+###[ FUNCTION EXPRESSIONS ]####################################################
+
+ expect-function-characteristics:
+ # https://mariadb.com/kb/en/create-function
+ - meta_prepend: true
+ - match: \b(?i:return)\b
+ scope: keyword.control.flow.return.sql
+ pop: 1
+ - match: \b(?i:not)\b
+ scope: keyword.operator.logical.sql
+ - match: \b(?i:deterministic)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:(?:contains|no)\s+sql|(?:reads|modifies)\s+sql\s+data)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:sql\s+security)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:definer|invoker)\b
+ scope: constant.language.user.sql
+ - match: \b(?i:soname)\b
+ scope: keyword.other.ddl.sql
+ - include: comment-keywords
+
+###[ INDEX EXPRESSIONS ]#######################################################
+
+ index-algorithm-args:
+ - match: \b(?i:algorithm)\b
+ scope: keyword.other.ddl.sql
+
+ index-clustering-args:
+ - match: \b(?i:clustering)\b
+ scope: keyword.other.ddl.sql
+
+ index-lock-args:
+ - match: \b(?i:lock)\b
+ scope: keyword.other.ddl.sql
+
+ index-parser-args:
+ - match: \b(?i:with\s+parser)\b
+ scope: keyword.other.ddl.sql
+ push: expect-other-name
+
+ index-type-args:
+ - match: \b(?i:using)\b
+ scope: keyword.other.ddl.sql
+ push: index-type-value
+
+ index-type-value:
+ - match: \b(?i:btree|hash|rtree)\b
+ scope: constant.language.sql
+ pop: 1
+ - include: else-pop
+
+ index-wait-args:
+ - match: \b(?i:nowait|wait)\b
+ scope: keyword.other.ddl.sql
+
+ index-other-args:
+ - match: \b(?i:ignored)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:key_block_size)\b
+ scope: keyword.other.ddl.sql
+
+###[ PARTITION EXPRESSIONS ]###################################################
+
+ maybe-partition-declaration-list:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set:
+ - inside-partition-declaration-list
+ - expect-partition-creation-name
+ - maybe-partition
+ - include: else-pop
+
+ partition-declaration-lists:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ push:
+ - inside-partition-declaration-list
+ - expect-partition-creation-name
+ - maybe-partition
+
+ inside-partition-declaration-list:
+ - meta_scope: meta.group.partitions.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ # partition and subpartition declarations
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+ push:
+ - expect-partition-creation-name
+ - maybe-partition
+ # partition parameters
+ - match: \b(?i:values)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:in|less\s+than)\b
+ scope: keyword.operator.logical.sql
+ push: maybe-group
+ - match: \b{{partition_parameters}}\b
+ scope: variable.parameter.sql
+ - include: partition-declaration-lists
+ - include: comment-keywords
+ - include: tablespaces
+ - include: expressions
+
+ maybe-partition:
+ - match: \b(?i:(?:sub)?partition)\b
+ scope: keyword.other.ddl.sql
+ - include: else-pop
+
+ partition-options:
+ # partition keywords
+ - match: \b(?i:(?:sub)?partition by)\b
+ scope: keyword.other.sql
+ - match: \b(?i:(?:sub)?partitions)\b
+ scope: keyword.other.sql
+ # partition arguments
+ - match: \b(?i:linear)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:hash|range|list)\b
+ scope: support.function.sql
+ push: maybe-group
+ - match: \b(?i:key)\b
+ scope: support.function.sql
+ push: maybe-column-name-list
+ - match: \b(?i:limit|system_time)\b
+ scope: keyword.other.sql
+ - include: intervals
+ - include: time-units
+
+ maybe-partition-name-list:
+ - include: partition-name-list
+ - include: else-pop
+
+ partition-name-list:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-partition-name-list
+
+ inside-partition-name-list:
+ - meta_scope: meta.group.partitions.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: comma-separators
+ - include: expect-partition-names
+
+###[ TABLE EXPRESSIONS ]#######################################################
+
+ table-options:
+ - include: comment-keywords
+ # table options with special treatment
+ - include: tablespaces
+ - match: \b(?i:like)\b
+ scope: keyword.other.sql
+ push: expect-table-name
+ - match: \b(?i:union)\b
+ scope: variable.parameter.sql
+ push: maybe-table-name-list
+ - match: \b(?i:with)\b
+ scope: keyword.other.sql
+ # common table options
+ - match: \b{{table_parameters}}\b
+ scope: variable.parameter.sql
+ - match: \b{{table_row_formats}}\b
+ scope: constant.language.sql
+ # common table option values
+ - match: \b(?i:after)\b
+ scope: keyword.other.position.sql
+ push: expect-column-name
+ - match: \b(?i:first|last)\b
+ scope: keyword.other.position.sql
+ - match: \b(?i:system\s+versioning)\b
+ scope: constant.language.sql
+
+ maybe-column-position:
+ - match: \b(?i:after)\b
+ scope: keyword.other.position.sql
+ set: expect-column-name
+ - match: \b(?i:first|last)\b
+ scope: keyword.other.position.sql
+ pop: 1
+ - include: else-pop
+
+ system-versioning:
+ - match: \b(?i:system\s+versioning)\b
+ scope: constant.language.sql
+ pop: 1
+
+ tablespaces:
+ - match: \b(?i:tablespace)\b
+ scope: variable.parameter.sql
+ push: maybe-tablespace-name
+
+ maybe-tablespace-name:
+ - include: assignment-operators
+ - include: expect-other-name
+
+ maybe-table-name-list:
+ - match: \(
+ scope: punctuation.section.sequence.begin.sql
+ set: inside-table-name-list
+ - include: assignment-operators
+ - include: else-pop
+
+ inside-table-name-list:
+ - meta_scope: meta.sequence.tables.sql
+ - match: \)
+ scope: punctuation.section.sequence.end.sql
+ pop: 1
+ - include: comma-separators
+ - include: expect-table-names
+
+###[ USER MANAGEMENT EXPRESSIONS ]#############################################
+
+ maybe-with-admin-user:
+ - meta_scope: meta.user.sql
+ - match: \b(?i:with)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - expect-user-name
+ - maybe-admin
+ - include: else-pop
+
+ maybe-admin:
+ - match: \b(?i:admin)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+ - include: else-pop
+
+ maybe-for-user:
+ - match: \b(?i:for)\b
+ scope: keyword.other.dml.sql
+ set: expect-user-name
+ - include: else-pop
+
+ maybe-user-assignment:
+ - match: =
+ scope: keyword.operator.assignment.sql
+ set: expect-user-name
+ - include: else-pop
+
+ expect-user-identification-list:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set:
+ - user-identification-list
+ - user-identification
+ - expect-user-name
+
+ user-identification-list:
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+ push:
+ - user-identification
+ - expect-user-name
+ - include: else-pop
+
+ user-identification:
+ - match: \b(?i:identified|by)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:password)\b
+ scope: storage.modifier.sql
+ - match: \b(?i:via)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - user-auth-list
+ - user-auth-args
+ - expect-other-name
+ - include: strings
+ - include: else-pop
+
+ user-name-list:
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+ push: expect-user-name
+ - include: else-pop
+
+ user-auth-list:
+ # used by CREATE/ALTER user
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+ push:
+ - user-auth-args
+ - expect-other-name
+ # used by GRANT statements
+ - match: \b(?i:or)\b
+ scope: keyword.operator.logical.sql
+ push:
+ - user-auth-args
+ - expect-other-name
+ - include: else-pop
+
+ user-auth-args:
+ - match: (?=,|\b(?i:account|on|or|require|with)\b)
+ pop: 1
+ - match: \b(?i:as)\b
+ scope: keyword.operator.assignment.alias.sql
+ - match: \b(?i:using)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:password)
+ scope: support.function.sql
+ push: function-call-arguments
+ - include: strings
+ - include: pop-on-top-level-reserved-word
+
+ user-options:
+ - include: user-account-options
+ - include: user-password-options
+ - include: user-resource-options
+ - include: user-tls-options
+ - include: numbers
+ - include: strings
+ - include: pop-on-top-level-reserved-word
+
+ user-account-options:
+ - match: \b(?i:account)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:unlock|lock)\b
+ scope: constant.language.sql
+
+ user-password-options:
+ - match: \b(?i:(password)\s+(expire))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ - match: \b(?i:default|never)\b
+ scope: constant.language.sql
+ - include: intervals
+ - include: time-units
+
+ user-resource-options:
+ - match: \b(?i:with)\b
+ scope: keyword.other.ddl.sql
+ - match: |-
+ \b(?xi: max_queries_per_hour | max_updates_per_hour
+ | max_connections_per_hour | max_user_connections
+ | max_statement_time )\b
+ scope: constant.language.sql
+
+ user-tls-options:
+ - match: \b(?i:require)\b
+ scope: keyword.other.ddl.sql
+ - match: \b(?i:and)\b
+ scope: keyword.operator.logical.sql
+ - match: \b(?i:ssl|x509|cipher|issuer|subject)\b
+ scope: constant.language.sql
+ - include: none-constants
+
+ user-privileges:
+ - meta_append: true
+ - match: \b(?i:super)\b
+ scope: constant.language.sql
+ - include: user-grant-privileges
+
+ user-grant-privileges:
+ - match: \b(?i:(?:grant|admin)\s+option)\b
+ scope: constant.language.sql
+
+ on-privilidge-level:
+ - match: \b(?i:on)\b
+ scope: keyword.context.sql
+ set: privilidge-level
+
+ privilidge-level:
+ # object type
+ - match: \b(?i:table|function|procedure|package)\b
+ scope: storage.type.sql
+ # wildcard privilidge level
+ - match: (\*)(?:(\.)(\*))?
+ scope: meta.other-name.sql
+ captures:
+ 1: constant.other.wildcard.asterisk.sql
+ 2: punctuation.accessor.dot.sql
+ 3: constant.other.wildcard.asterisk.sql
+ pop: 1
+ # named privilidge level: database, table or method
+ - include: expect-other-name
+
+###[ TABLE NAMES OR SUBQUERIES ]###############################################
+
+ table-subquery:
+ # https://mariadb.com/kb/en/join-syntax
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: table-subquery-begin
+ - match: \{
+ scope: punctuation.section.braces.begin.mysql
+ set:
+ - table-braced-subquery-body
+ - maybe-on-table
+
+ table-braced-subquery-body:
+ - meta_scope: meta.braces.mysql
+ - match: \}
+ scope: punctuation.section.braces.end.mysql
+ pop: 1
+ - include: join-expressions
+
+ maybe-on-table:
+ - match: \b(?i:on)\b
+ scope: keyword.other.dml.sql
+ set: table-name-or-subquery
+ - include: else-pop
+
+ table-subquery-begin:
+ - meta_include_prototype: false
+ - meta_scope: meta.group.sql
+ - include: comments
+ # table subquery
+ - match: (?=(?i:select)\b)
+ set:
+ - maybe-table-alias
+ - inside-group
+ # table reference list
+ - match: (?=\S)
+ set: inside-table-reference-list
+
+ inside-table-reference-list:
+ - meta_scope: meta.group.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: comma-separators
+ - include: expect-table-references
+
+ expect-table-references:
+ - meta_include_prototype: false
+ - match: (?=\S)
+ push:
+ - join-condition
+ - table-name-or-subquery
+
+ table-name-not-function-call:
+ - meta_include_prototype: false
+ - match: ''
+ set:
+ - maybe-index-hint-list
+ - maybe-table-alias
+ - table-name-fail-if-function-call
+ - table-name
+ - single-identifier
+
+ maybe-table-alias:
+ - meta_prepend: true
+ - match: (?=(?i:force|ignore|on|use|using)\b)
+ pop: 1
+ - match: \b(?i:partition)\b
+ scope: keyword.other.dml.sql
+ push: maybe-partition-name-list
+
+###[ INDEX HINTS ]#############################################################
+
+ maybe-index-hint-list:
+ # https://mariadb.com/kb/en/join-syntax
+ - include: index-hint-lists
+ - include: comma-separators
+ - include: else-pop
+
+ index-hint-lists:
+ - match: \b(?i:(?:force|ignore|use)\s+(?:index|key))\b
+ scope: keyword.other.dml.sql
+ push:
+ - maybe-index-name-list
+ - maybe-index-hint-target
+
+ maybe-index-hint-target:
+ - match: \b(?i:for\s+(?:join|(?:group|order)\s+by))\b
+ scope: keyword.other.dml.sql
+ pop: 1
+ - include: else-pop
+
+ maybe-index-name-list:
+ - match: \(
+ scope: punctuation.section.sequence.begin.sql
+ set: inside-index-name-list
+ - include: else-pop
+
+ inside-index-name-list:
+ - meta_scope: meta.group.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: comma-separators
+ - include: expect-index-names
+
+###[ TYPES ]###################################################################
+
+ intervals:
+ - match: \b(?i:interval)\b
+ scope: storage.type.interval.sql
+
+ built-in-types:
+ - meta_prepend: true
+ # https://mariadb.com/kb/en/row
+ - match: \b(?i:row)\b
+ scope: storage.type.sql
+ push:
+ - after-type
+ - maybe-column-declaration-list
+ - match: \b(?i:set)(?=\s*\()
+ scope: storage.type.sql
+ push:
+ - after-type
+ - maybe-group
+
+ built-in-type:
+ - meta_prepend: true
+ # https://mariadb.com/kb/en/row
+ - match: \b(?i:row)\b
+ scope: storage.type.sql
+ set:
+ - after-type
+ - maybe-column-declaration-list
+ - match: \b(?i:set)\b
+ scope: storage.type.sql
+ set:
+ - after-type
+ - maybe-group
+
+ after-type:
+ - meta_prepend: true
+ - match: \b(?i:with(?:out)?\s+time\s+zone)\b
+ scope: storage.modifier.sql
+ pop: 1
+
+###[ IDENTIFIERS ]#############################################################
+
+ expect-user-name-declaration:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [user-name-declaration, user-identifier]
+
+ expect-user-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - include: built-in-user-function-call
+ - match: (?=\S)
+ set: [user-name, user-identifier]
+
+ user-identifier:
+ # https://mariadb.com/kb/en/grant/#account-names
+ - meta_include_prototype: false
+ - include: pop-on-top-level-reserved-word
+ - match: ''
+ set:
+ - identifier-host-accessor
+ - identifier-part
+
+ identifier-host-accessor:
+ - meta_include_prototype: false
+ - match: \s*(@)
+ captures:
+ 1: punctuation.accessor.at.sql
+ set: identifier-host-part
+ - include: immediately-pop
+
+ identifier-host-part:
+ - meta_include_prototype: false
+ - match: \%
+ scope: constant.other.wildcard.percent.sql
+ pop: 1
+ - match: (')(%)(')
+ captures:
+ 1: punctuation.definition.identifier.begin.sql
+ 2: constant.other.wildcard.percent.sql
+ 3: punctuation.definition.identifier.end.sql
+ pop: 1
+ - match: (")(%)(")
+ captures:
+ 1: punctuation.definition.identifier.begin.sql
+ 2: constant.other.wildcard.percent.sql
+ 3: punctuation.definition.identifier.end.sql
+ pop: 1
+ - match: (`)(%)(`)
+ captures:
+ 1: punctuation.definition.identifier.begin.sql
+ 2: constant.other.wildcard.percent.sql
+ 3: punctuation.definition.identifier.end.sql
+ pop: 1
+ - include: identifier-part
+
+###[ LITERALS ]################################################################
+
+ literals-and-variables:
+ - meta_append: true
+ - include: time-units
+ - include: variables
+
+ comment-keywords:
+ - match: \b(?i:comment)\b
+ scope: variable.parameter.sql
+
+ constants:
+ - meta_append: true
+ - include: bool-constants
+ - include: none-constants
+ - match: \b{{builtin_constants}}\b
+ scope: constant.language.sql
+
+ bool-constants:
+ - include: booleans
+ - match: \b(?i:yes|no)\b
+ scope: constant.language.boolean.sql
+
+ none-constants:
+ - match: \b(?i:none)\b
+ scope: constant.language.null.sql
+
+ none-constant:
+ - match: \b(?i:none)\b
+ scope: constant.language.null.sql
+ pop: 1
+
+ time-units:
+ - match: \b{{time_units}}(?!\()\b
+ scope: keyword.other.unit.sql
+
+ variables:
+ - match: (:){{simple_identifier}}\b
+ scope: variable.parameter.sql
+ captures:
+ 1: punctuation.definition.variable.sql
+ - match: (@@){{simple_identifier}}\b
+ scope: variable.language.sql
+ captures:
+ 1: punctuation.definition.variable.sql
+ - match: (@){{simple_identifier}}\b
+ scope: variable.other.sql
+ captures:
+ 1: punctuation.definition.variable.sql
+
+ regexps:
+ - match: /(?=\S.*/)
+ scope: punctuation.definition.string.begin.sql
+ push: inside-regexp
+
+ inside-regexp:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.regexp.sql string.regexp.sql
+ - match: /
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - include: string-interpolations
+ - match: \\/
+ scope: constant.character.escape.slash.sql
+
+ strings:
+ - meta_append: true
+ - include: double-quoted-strings
+ - include: interpolations
+
+ double-quoted-strings:
+ - match: \"
+ scope: punctuation.definition.string.begin.sql
+ push: inside-double-quoted-string
+
+ inside-double-quoted-string:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.sql string.quoted.double.sql
+ - match: \"\"
+ scope: constant.character.escape.sql
+ - match: \"
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - include: string-interpolations
+
+ interpolations:
+ - match: \%\{
+ scope: punctuation.definition.string.begin.sql
+ push: inside-interpolation
+
+ inside-interpolation:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.sql string.other.quoted.brackets.sql
+ - match: \}
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - include: string-interpolations
+
+ string-interpolations:
+ - meta_include_prototype: false
+ - match: (#\{)([^\}]*)(\})
+ scope: meta.interpolation.sql
+ captures:
+ 1: punctuation.section.interpolation.begin.sql
+ 3: punctuation.section.interpolation.end.sql
+ push: clear-scope-imediately-pop
+
+###[ LIKE EXPRESSIONS ]########################################################
+
+ like-string-not-followed-by-escape:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-fail
+ - inside-like-single-quoted-string-slash-escape
+ - include: else-pop
+
+ like-escape-character-slash:
+ - match: (\')(\\\\)(\')
+ scope: meta.string.escape.sql string.quoted.single.sql
+ captures:
+ 1: punctuation.definition.string.begin.sql
+ 2: constant.character.escape.sql
+ 3: punctuation.definition.string.end.sql
+ pop: 1
+ - include: like-else-fail
+
+###[ OPERATORS ]###############################################################
+
+ operators:
+ - meta_append: true
+ - match: \|\|
+ scope: keyword.operator.concatenation.sql
+ - match: \!
+ scope: keyword.operator.logical.sql
+ - match: \b(?i:div|mod)\b
+ scope: keyword.operator.arithmetic.sql
+
+###[ PROTOTYPES ]##############################################################
+
+ clear-scope-imediately-pop:
+ - clear_scopes: 1
+ - include: immediately-pop
diff --git a/SQL/PostgreSQL.sublime-syntax b/SQL/PostgreSQL.sublime-syntax
new file mode 100644
index 0000000000..04a64f1940
--- /dev/null
+++ b/SQL/PostgreSQL.sublime-syntax
@@ -0,0 +1,361 @@
+%YAML 1.2
+---
+name: PostgreSQL
+scope: source.sql.psql
+version: 2
+
+extends: Packages/SQL/MySQL.sublime-syntax
+
+file_extensions:
+ - psql
+
+variables:
+ simple_types: |-
+ (?xi: smallint | integer | bigint | real | double\s+precision
+ | smallserial | serial | bigserial
+ | money
+ | bytea
+ | boolean
+ | times? | timestamp(?:s | tz)? | date | interval
+ | int4range | int8range | numrange | tsrange | tstzrange | daterange
+ | point | line | lseg | box | path | polygon | circle
+ | cidr | inet | macaddr | macaddr8
+ | tsvector | tsquery
+ | uuid
+ | text | xml | jsonb? )
+
+ types_with_optional_number: |-
+ (?xi: (?: bit | character ) (?:\s+varying)? | char | decimal | numeric | varchar )
+
+contexts:
+
+ sql:
+ - meta_prepend: true
+ - include: declare-statements
+
+ statements:
+ - meta_prepend: true
+ - match: (\$\$)\s+(LANGUAGE)\s+(\w+)(?:\s+(IMMUTABLE|STABLE)\b)?
+ captures:
+ 1: punctuation.section.block.end.psql
+ 2: keyword.other.psql
+ 3: constant.language.psql
+ 4: storage.modifier.psql
+ - match: \$\$
+ scope: punctuation.section.block.begin.psql
+ - match: \b(?i:if)\b
+ scope: keyword.control.conditional.if.psql
+ - match: \b(?i:for)\b
+ scope: keyword.control.loop.psql
+ push:
+ - declaration-variable-name
+ - single-identifier
+ - match: \b(?i:loop)\b
+ scope: keyword.control.loop.psql
+ # TODO: priortise variables over columns when not in a select statement etc.
+
+ built-in-type:
+ - meta_prepend: true
+ - match: |-
+ (?xi)
+ \b{{types_with_optional_number}}\b
+ (\[)(\])
+ scope: storage.type.sql
+ captures:
+ 1: punctuation.section.brackets.begin.psql
+ 2: punctuation.section.brackets.end.psql
+ set: maybe-group
+
+###[ DECLARE STATEMENTS ]######################################################
+
+ declare-statements:
+ - match: \b(?i:declare)\b
+ scope: keyword.declaration.variable.psql
+ push: inside-declaration
+
+ inside-declaration:
+ - match: (?=\S)
+ set:
+ - expect-type
+ - declaration-variable-name
+ - single-identifier
+
+ declaration-variable-name:
+ - meta_include_prototype: false
+ - meta_scope: variable.other.psql
+ - include: immediately-pop
+
+###[ DDL CREATE STATEMENTS ]###################################################
+
+ create-target:
+ - meta_prepend: true
+ - include: create-extension
+
+ create-extension:
+ # https://www.postgresql.org/docs/current/sql-createextension.html
+ - match: \b(?i:extension|domain)\b
+ scope: keyword.other.ddl.psql
+ set:
+ - create-extension-args
+ - expect-extension-name-declaration
+ - create-extension-condition
+
+ create-extension-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-extension-args:
+ - meta_scope: meta.extension.sql
+ - match: \b(?i:with)\b
+ scope: keyword.other.psql
+ - match: \b(?i:schema)\b
+ scope: storage.modifier.psql
+ push: expect-schema-name
+ - include: extension-attributes
+ - include: expressions
+
+ create-index-condition:
+ # https://www.postgresql.org/docs/current/sql-createindex.html
+ - meta_prepend: true
+ - match: \b(?i:concurrently)\b
+ scope: keyword.other.ddl.psql
+
+ create-common-args:
+ - meta_prepend: true
+ - match: \b(?i:after(?:\s+(?:insert|update|or))+)\b
+ scope: keyword.other.psql
+ push: maybe-on-table-name
+ - match: \b(?i:for\s+each\s+row\s+execute\s+procedure)\b
+ scope: keyword.other.psql
+
+###[ DDL DROP STATEMENTS ]#####################################################
+
+ drop-target:
+ - meta_prepend: true
+ - include: drop-extension
+
+ drop-extension:
+ # https://www.postgresql.org/docs/current/sql-dropextension.html
+ - match: \b(?i:extension|domain)\b
+ scope: keyword.other.ddl.psql
+ set:
+ - drop-extension-args
+ - expect-extension-name
+ - drop-extension-condition
+
+ drop-extension-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-extension-args:
+ - meta_scope: meta.extension.psql
+ - match: ','
+ scope: punctuation.separator.sequence.psql
+ push: expect-extension-name
+ - include: extension-attributes
+ - include: else-pop
+
+###[ DDL ALTER STATEMENTS ]####################################################
+
+ alter-target:
+ - meta_prepend: true
+ # https://www.postgresql.org/docs/current/sql-alterextension.html
+ - match: \b(?i:extension|domain)\b
+ scope: keyword.other.ddl.psql
+ set:
+ - alter-extension-args
+ - expect-extension-name
+
+ alter-extension-args:
+ - match: \b(?i:add|drop)\b
+ scope: keyword.other.ddl.sql
+ push: expect-member-name
+ - match: \b(?i:(set)\s+(schema))\b
+ captures:
+ 1: keyword.other.ddl.psql
+ 2: storage.modifier.psql
+ push: expect-schema-name
+ - match: \b(?i:(update)\s+(to))\b
+ captures:
+ 1: keyword.other.ddl.psql
+ 2: keyword.other.ddl.psql
+ - include: numbers
+ - include: else-pop
+
+###[ DDL STATEMENT PROTOTYPES ]################################################
+
+ on-table-names:
+ - match: \b(?i:(on)(?:\s+(only))?)\b
+ captures:
+ 1: keyword.other.sql
+ 2: keyword.other.psql
+ push: expect-table-name
+
+###[ EXPRESSIONS ]#############################################################
+
+ expressions:
+ - meta_prepend: true
+ - match: \b(?i:array)\b
+ scope: keyword.declaration.psql
+ - match: \[
+ scope: punctuation.section.brackets.begin.psql
+ - match: \]
+ scope: punctuation.section.brackets.end.psql
+
+###[ COLUMN EXPRESSIONS ]######################################################
+
+ inside-column-declaration-list:
+ - meta_prepend: true
+ - match: \b(?i:unique)\b
+ scope: keyword.other.psql
+
+###[ EXTENSION EXPRESSIONS ]###################################################
+
+ extension-attributes:
+ - match: \b(?i:cascade|restrict|version)\b
+ scope: storage.modifier.psql
+
+###[ FUNCTION EXPRESSIONS ]####################################################
+
+ expect-function-characteristics:
+ # https://mariadb.com/kb/en/create-function
+ - meta_prepend: true
+ - match: \b(?i:as)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+
+###[ IDENTIFIERS ]#############################################################
+
+ expect-extension-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [extension-name, single-identifier]
+
+ extension-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.extension-name.psql
+ - include: immediately-pop
+
+ expect-extension-name-declaration:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [extension-name-declaration, single-identifier]
+
+ extension-name-declaration:
+ - meta_include_prototype: false
+ - meta_content_scope: entity.name.namespace.psql
+ - include: immediately-pop
+
+ expect-member-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [member-name, single-identifier]
+
+ member-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.member-name.psql
+ - include: immediately-pop
+
+ expect-member-name-declaration:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [member-name-declaration, single-identifier]
+
+ member-name-declaration:
+ - meta_include_prototype: false
+ - meta_content_scope: entity.name.member.psql
+ - include: immediately-pop
+
+ expect-schema-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [schema-name, single-identifier]
+
+ schema-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.schema-name.psql
+ - include: immediately-pop
+
+###[ OPERATORS ]###############################################################
+
+ operators:
+ - meta_prepend: true
+ - match: '::'
+ scope: keyword.operator.cast.psql
+ push: expect-type
+ - match: ':='
+ scope: keyword.operator.assignment.psql
+ - match: ':(?!:)'
+ scope: keyword.operator.range.psql
+ - include: regex-operators
+ - match: \.\.
+ scope: keyword.operator.psql
+
+ regex-operators:
+ # https://www.postgresql.org/docs/7.4/functions-matching.html#FUNCTIONS-POSIX-REGEXP
+ - match: '!?~\*?'
+ scope: keyword.operator.comparison.psql
+ push: expect-regexp
+
+ expect-regexp:
+ - match: \'
+ scope: meta.string.regexp.psql punctuation.definition.string.begin.psql
+ embed: scope:source.regexp
+ embed_scope: meta.string.regexp.psql
+ escape: \'
+ escape_captures:
+ 0: meta.string.regexp.psql punctuation.definition.string.end.psql
+ pop: 1
+ - include: else-pop
+
+ strings:
+ - meta_prepend: true
+ # https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
+ - match: (?i:E)\'
+ scope: punctuation.definition.string.begin.sql
+ push: inside-single-quoted-escape-string
+ - match: \'(?=[^']+'::bytea\b)
+ scope: punctuation.definition.string.begin.sql
+ push: inside-single-quoted-bytea-string
+
+ inside-single-quoted-escape-string:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.sql string.quoted.single.sql
+ - match: \'\'
+ scope: constant.character.escape.sql
+ - match: \'
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - match: \\[0-7]{1,3}
+ scope: constant.character.escape.sql
+ - match: \\x\h{1,2}
+ scope: constant.character.escape.sql
+ - match: \\u\h{4}
+ scope: constant.character.escape.sql
+ - match: \\U\h{8}
+ scope: constant.character.escape.sql
+ - include: string-escapes
+
+ inside-single-quoted-bytea-string:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.sql string.quoted.single.sql
+ - match: \'\'
+ scope: constant.character.escape.sql
+ - match: \'
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - match: \\[0-7]{1,3}
+ scope: constant.character.escape.sql
+ - match: \\x\h{8}
+ scope: constant.character.escape.sql
+ - include: string-escapes
diff --git a/SQL/SQL (basic).sublime-syntax b/SQL/SQL (basic).sublime-syntax
new file mode 100644
index 0000000000..25818cce48
--- /dev/null
+++ b/SQL/SQL (basic).sublime-syntax
@@ -0,0 +1,1659 @@
+%YAML 1.2
+---
+name: SQL (Basic)
+scope: source.sql.basic
+version: 2
+hidden: true
+
+variables:
+ string_escape: (?:\\.)
+ simple_identifier: (?:\w+)
+ simple_identifier_break: (?!\w)
+
+ toplevel_reserved: |-
+ (?xi: alter | create | cross | delete | drop | from | grant | group | inner | insert | join
+ | left | on | order | outer | revoke | right | select | set | truncate | union
+ | update | where )
+ additional_toplevel_reserved: (?!)
+
+ # TODO: not all are supported by all dialects!
+ ddl_target: |-
+ (?xi: {{ddl_target_other}}
+ | (?: {{ddl_target_function_modifier}} \s+ )? {{ddl_target_function}}
+ | (?: {{ddl_target_index_modifier}} \s+ )? index
+ | (?: {{ddl_target_table_modifier}} \s+ )? table )
+ ddl_target_function: |-
+ (?xi: procedure | function )
+ ddl_target_other: |-
+ (?xi: aggregate | column | constraint | conversion | database | domain | group
+ | language | member | operator\s+class | operator | role | rule | schema | sequence
+ | tablespace | trigger | type | user | view )
+
+ ddl_target_inside_alter_table: |-
+ (?xi: constraint )
+
+ ddl_target_function_modifier: |-
+ (?xi: aggregate )
+ ddl_target_index_modifier: |-
+ (?xi: clustered | fulltext | spatial | unique )
+ ddl_target_table_modifier: |-
+ (?xi: temp(?:orary)? )
+
+ function_parameter_modifier: |-
+ (?xi: inout | in | out )
+
+ simple_types: |-
+ (?xi: boolean | bool | year )
+
+ types_with_optional_number: |-
+ (?xi: bit | datetime | int | number | n?(?:var)?char | varbinary )
+
+ type_modifiers: |-
+ (?xi: signed | unsigned | zerofill )
+
+ builtin_scalar_functions: |-
+ (?xi: current_(?: date | time(?:stamp)? ) )
+
+ builtin_user_functions: |-
+ (?xi: (?: current | session | system )_user )
+
+contexts:
+ prototype:
+ - include: comments
+
+ main:
+ - include: sql
+
+ sql:
+ - include: statements
+ - include: statement-terminators
+ - include: expressions-or-column-names
+
+ statements:
+ - include: create-statements
+ - include: drop-statements
+ - include: alter-statements
+ - include: dml-statements
+ - include: grant-statements
+ - include: revoke-statements
+ - include: other-statements
+
+###[ COMMENTS ]################################################################
+
+ comments:
+ - include: double-dash-comments
+ - include: block-comments
+
+ double-dash-comments:
+ - match: '--'
+ scope: punctuation.definition.comment.sql
+ push: inside-double-dash-comment
+
+ block-comments:
+ - match: /\*(?:\*(?!/))+
+ scope: punctuation.definition.comment.begin.sql
+ push: inside-comment-docblock
+ - match: /\*
+ scope: punctuation.definition.comment.begin.sql
+ push: inside-comment-block
+
+ inside-double-dash-comment:
+ - meta_include_prototype: false
+ - meta_scope: comment.line.double-dash.sql
+ - match: \n
+ pop: 1
+
+ inside-comment-docblock:
+ - meta_include_prototype: false
+ - meta_scope: comment.block.documentation.sql
+ - match: \*+/
+ scope: punctuation.definition.comment.end.sql
+ pop: 1
+ - match: ^\s*(\*)(?!\**/)
+ captures:
+ 1: punctuation.definition.comment.sql
+
+ inside-comment-block:
+ - meta_include_prototype: false
+ - meta_scope: comment.block.sql
+ - match: \*+/
+ scope: punctuation.definition.comment.end.sql
+ pop: 1
+
+###[ DDL CREATE STATEMENTS ]###################################################
+
+ create-statements:
+ - match: \b(?i:create)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - create-meta
+ - create-target
+
+ create-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.create.sql
+ - include: immediately-pop
+
+ create-target:
+ - include: create-function
+ - include: create-index
+ - include: create-table
+ - include: create-other
+ - include: else-pop
+
+ create-function:
+ - match: \b(?:({{ddl_target_function_modifier}})\s+)?({{ddl_target_function}})\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - expect-function-characteristics
+ - expect-function-parameters
+ - expect-function-creation-name
+ - create-function-condition
+
+ create-function-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-index:
+ - match: \b(?i:(?:({{ddl_target_index_modifier}})\s+)?(index))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - create-index-args
+ - expect-index-creation-name
+ - create-index-condition
+
+ create-index-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-index-args:
+ - meta_scope: meta.index.sql
+ - include: on-table-names
+ - include: create-common-args
+
+ create-table:
+ - match: \b(?i:(?:({{ddl_target_table_modifier}})\s+)?(table))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - create-table-args
+ - maybe-column-declaration-list
+ - expect-table-creation-name
+ - create-table-condition
+
+ create-table-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-table-args:
+ - meta_scope: meta.table.sql
+ - include: create-common-args
+
+ create-other:
+ - match: \b{{ddl_target_other}}\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-other-args
+ - expect-other-creation-name
+ - create-other-condition
+
+ create-other-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ create-other-args:
+ - match: \b(?i:(as)\s+(table))\b
+ captures:
+ 1: keyword.context.block.sql
+ 2: support.type.sql
+ set: maybe-column-declaration-list
+ - match: \b(?i:as)\b
+ scope: keyword.context.block.sql
+ pop: 1
+ - include: grant
+ - include: on-table-names
+ - include: create-common-args
+
+ create-common-args:
+ - include: expressions
+ - include: pop-on-top-level-reserved-word
+
+###[ DDL DROP STATEMENTS ]#####################################################
+
+ drop-statements:
+ - match: \b(?i:drop)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - drop-meta
+ - drop-target
+
+ drop-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.drop.sql
+ - include: immediately-pop
+
+ drop-target:
+ - include: drop-function
+ - include: drop-index
+ - include: drop-table
+ - include: drop-other
+ - include: else-pop
+
+ drop-function:
+ - match: \b{{ddl_target_function}}\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-function-args
+ - expect-function-name
+ - drop-function-condition
+
+ drop-function-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-function-args:
+ - meta_include_prototype: false
+ - meta_scope: meta.function.sql
+ - include: immediately-pop
+
+ drop-index:
+ - match: \b(?i:index)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-index-args
+ - expect-index-name
+ - drop-index-condition
+
+ drop-index-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-index-args:
+ - meta_scope: meta.index.sql
+ - include: maybe-on-table-name
+
+ drop-table:
+ - match: \b(?i:(?:({{ddl_target_table_modifier}})\s+)?(table))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - drop-table-args
+ - expect-table-name
+ - drop-table-condition
+
+ drop-table-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-table-args:
+ - meta_include_prototype: false
+ - meta_scope: meta.table.sql
+ - include: immediately-pop
+
+ drop-other:
+ - match: \b(?i:user)\b
+ scope: storage.type.sql
+ set:
+ - expect-user-name
+ - maybe-condition
+ - match: \b{{ddl_target_other}}\b
+ scope: keyword.other.ddl.sql
+ set:
+ - drop-other-args
+ - expect-other-name
+ - drop-other-condition
+
+ drop-other-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ drop-other-args:
+ - include: maybe-on-table-name
+
+###[ DDL ALTER STATEMENTS ]####################################################
+
+ alter-statements:
+ - match: \b(?i:alter)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - alter-meta
+ - alter-target
+
+ alter-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.alter.sql
+ - include: immediately-pop
+
+ alter-target:
+ - include: alter-function
+ - include: alter-index
+ - include: alter-table
+ - include: alter-other
+ - include: else-pop
+
+###[ DDL ALTER FUNCTION STATEMENTS ]###########################################
+
+ alter-function:
+ - match: \b(?:({{ddl_target_function_modifier}})\s+)?({{ddl_target_function}})\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - expect-function-characteristics
+ - expect-function-parameters
+ - expect-function-name
+ - alter-function-condition
+
+ alter-function-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+###[ DDL ALTER INDEX STATEMENTS ]##############################################
+
+ alter-index:
+ - match: \b(?i:(?:({{ddl_target_index_modifier}})\s+)?(index))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - alter-index-args
+ - expect-index-name
+ - alter-index-condition
+
+ alter-index-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-index-args:
+ - include: alter-common
+ - include: pop-on-top-level-reserved-word
+ - include: expressions-or-column-names
+
+###[ DDL ALTER TABLE STATEMENTS ]##############################################
+
+ alter-table:
+ - match: \b(?i:(?:({{ddl_target_table_modifier}})\s+)?(table))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ set:
+ - alter-table-args
+ - expect-table-name
+ - alter-table-condition
+
+ alter-table-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-table-args:
+ - include: alter-columns
+ - include: alter-common
+ - include: pop-on-top-level-reserved-word
+ - include: expressions-or-column-names
+
+ alter-other:
+ - match: \b{{ddl_target_other}}\b
+ scope: keyword.other.ddl.sql
+ set:
+ - alter-other-args
+ - expect-other-name
+ - alter-other-condition
+
+ alter-other-condition:
+ - meta_include_prototype: false
+ - include: maybe-condition
+
+ alter-other-args:
+ - include: alter-common
+ - include: else-pop
+
+ alter-columns:
+ - match: \b(?i:(?:(add|alter)\b(?:\s+(column)\b|(?!\s+(?:table|{{ddl_target_inside_alter_table}})\b))))
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ push:
+ - expect-type
+ - expect-column-name-declaration
+ - match: \b(?i:(drop)(?:\s+(column)\b|(?!\s+{{ddl_target}}\b)))
+ scope: keyword.other.ddl.sql
+ push: expect-column-name
+
+ alter-common:
+ - match: \b(?i:(add)\s+(constraint))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ push:
+ - maybe-column-modifier
+ - expect-constraint-name
+ - match: \b(?i:(add)\s+(?:({{ddl_target_index_modifier}})\s+)?(index))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ 3: keyword.other.ddl.sql
+ - match: \b(?i:(add)\s+(primary|foreign)\s+(key))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ 3: keyword.other.ddl.sql
+
+###[ DDL STATEMENT PROTOTYPES ]################################################
+
+ maybe-on-table-name:
+ - include: on-table-names
+ - include: else-pop
+
+ on-table-names:
+ - match: \b(?i:on)\b
+ scope: keyword.other.sql
+ push: expect-table-name
+
+###[ DML STATEMENTS ]##########################################################
+
+ dml-statements:
+ - match: \b(?i:select)\b
+ scope: keyword.other.dml.sql
+ - match: \b(?i:union(?:\s+all)?)\b
+ scope: keyword.other.dml.sql
+ - match: \b(?i:(?:delete(?:\s+from)?))\b
+ scope: keyword.other.dml.sql
+ push: dml-delete
+ - match: \b(?i:update)\b
+ scope: keyword.other.dml.sql
+ push: dml-update
+ - match: \b(?i:(?:insert\s+into|truncate))\b
+ scope: keyword.other.dml.sql
+ push: expect-table-name
+ - include: set-statements
+ # expressions
+ - match: \b(?i:(?:default\s+)?values)\b
+ scope: keyword.other.dml.II.sql
+ - include: distinct
+ - include: join-expressions
+ - match: \b(?i:group\s+by|order\s+by|having|where)\b
+ scope: keyword.other.dml.sql
+ - match: \b(?i:from)\b
+ scope: keyword.other.dml.sql
+ push: table-name-or-subquery
+ - match: \b(?i:asc|desc)\b
+ scope: keyword.other.order.sql
+
+ dml-delete:
+ - include: expect-table-name
+
+ dml-update:
+ - match: (?={{simple_identifier}}\s*=)
+ pop: 1
+ - include: expect-table-name
+
+ distinct:
+ - match: \b(?i:distinct)\b
+ scope: keyword.other.dml.sql
+
+ join-expressions:
+ - match: \b(?i:(?:(?:cross|inner|(?:full|left|right)(?:\s+outer)?)\s+)?join)\b
+ scope: keyword.other.dml.sql
+ push:
+ - join-condition
+ - table-name-or-subquery
+
+ join-condition:
+ - match: \b(?i:on)\b
+ scope: keyword.control.conditional.sql
+ set: conditional-expression
+ - include: else-pop
+
+ conditional-expression:
+ - match: (?=[,;)}]|\b(?:{{toplevel_reserved}}|{{additional_toplevel_reserved}})\b)
+ pop: 1
+ - include: expressions
+ - include: expect-column-names
+
+###[ DML SET STATEMENTS ]######################################################
+
+ set-statements:
+ - match: \b(?i:set)\b(?!\s*\()
+ scope: keyword.other.dml.sql
+ push:
+ - set-meta
+ - set-target
+
+ set-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.set.sql
+ - include: immediately-pop
+
+ set-target:
+ - include: else-pop
+
+###[ GRANT STATEMENTS ]########################################################
+
+ grant-statements:
+ - match: \b(?i:grant(?:\s+with\s+grant\s+option)?)\b
+ scope: keyword.other.authorization.sql
+ push:
+ - grant-meta
+ - grant
+
+ grant-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.grant.sql
+ - include: immediately-pop
+
+###[ REVOKE STATEMENTS ]#######################################################
+
+ revoke-statements:
+ - match: \b(?i:revoke)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - revoke-meta
+ - grant
+
+ revoke-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.statement.revoke.sql
+ - include: immediately-pop
+
+###[ OTHER STATEMENTS ]########################################################
+
+ other-statements: []
+
+###[ EXPRESSIONS ]#############################################################
+
+ expressions-or-column-names:
+ - include: wildcard-identifiers
+ - include: expressions
+ - include: expect-column-names
+
+ expressions:
+ - include: groups
+ - include: comma-separators
+ - include: operators
+ - include: column-alias-expressions
+ - include: case-expressions
+ - include: collate-expressions
+ - include: constraint-expressions
+ - include: literals-and-variables
+ - include: function-calls
+ - include: illegal-stray-brackets
+ - include: illegal-stray-parens
+ - match: (?=;)
+ pop: 1
+
+ column-alias-expressions:
+ - match: \b(?i:as)\b
+ scope: keyword.operator.assignment.alias.sql
+ push: expect-column-alias-name
+
+ table-alias-expression:
+ - match: \b(?i:as)\b
+ scope: keyword.operator.assignment.alias.sql
+ set: expect-table-alias-name
+
+ case-expressions:
+ - match: \b(?i:case)\b
+ scope: keyword.control.conditional.case.sql
+ push: inside-case-expression
+
+ inside-case-expression:
+ - meta_scope: meta.statement.conditional.case.sql
+ - match: \b(?i:end)\b
+ scope: keyword.control.conditional.end.sql
+ pop: 1
+ - match: \b(?i:(case)\s+(when))\b
+ captures:
+ 1: keyword.control.conditional.case.sql
+ 2: keyword.control.conditional.when.sql
+ - match: \b(?i:when)\b
+ scope: keyword.control.conditional.when.sql
+ - match: \b(?i:then)\b
+ scope: keyword.control.conditional.then.sql
+ - match: \b(?i:else)\b
+ scope: keyword.control.conditional.else.sql
+ - include: expressions-or-column-names
+
+ collate-expressions:
+ - match: \b(?i:collate)\b
+ scope: keyword.other.sql
+ push: inside-collate-expression
+
+ inside-collate-expression:
+ - match: '{{simple_identifier}}'
+ scope: support.constant.sql
+ pop: 1
+ - include: else-pop
+
+ constraint-expressions:
+ - match: \b(?i:constraint)\b
+ scope: storage.modifier.sql
+ push: expect-constraint-name
+
+ maybe-check:
+ - match: \b(?i:check)\b
+ scope: keyword.other.sql
+ set: maybe-group
+ - include: else-pop
+
+ maybe-column:
+ - match: \b(?i:column)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+ - include: else-pop
+
+ maybe-to:
+ - match: \b(?i:to)\b
+ scope: keyword.other.ddl.sql
+ pop: 1
+ - include: else-pop
+
+###[ FUNCTION EXPRESSIONS ]####################################################
+
+ function-calls:
+ - include: built-in-aggregate-function-calls
+ - include: built-in-scalar-function-calls
+ - include: built-in-user-function-calls
+ - include: user-defined-function-calls
+
+ built-in-aggregate-function-calls:
+ # List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html
+ - match: \b(?i:AVG|COUNT|MIN|MAX|SUM)(?=\s*\()
+ scope: support.function.aggregate.sql
+ push: function-call-arguments
+
+ built-in-scalar-function-calls:
+ # List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html
+ - match: \b{{builtin_scalar_functions}}\b
+ scope: support.function.scalar.sql
+ push: function-call-arguments
+
+ built-in-user-function-calls:
+ - match: \b{{builtin_user_functions}}\b
+ scope: support.function.user.sql
+ push: function-call-arguments
+
+ built-in-user-function-call:
+ - match: \b{{builtin_user_functions}}\b
+ scope: support.function.user.sql
+ set: function-call-arguments
+
+ user-defined-function-calls:
+ - match: \b{{simple_identifier}}(?=\s*\()
+ scope: support.function.sql
+ push: function-call-arguments
+
+ function-call-arguments:
+ - meta_include_prototype: false
+ - meta_scope: meta.function-call.sql
+ - match: \(
+ scope: meta.group.sql punctuation.section.arguments.begin.sql
+ set: inside-function-call-arguments
+ - include: else-pop
+
+ inside-function-call-arguments:
+ - meta_content_scope: meta.function-call.sql meta.group.sql
+ - match: \)
+ scope: meta.function-call.sql meta.group.sql punctuation.section.arguments.end.sql
+ pop: 1
+ - match: ','
+ scope: punctuation.separator.arguments.sql
+ - include: distinct
+ - include: expressions-or-column-names
+
+###[ GROUPS EXPRESSIONS ]######################################################
+
+ maybe-group:
+ - include: group
+ - include: else-pop
+
+ group:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-group
+
+ groups:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ push: inside-group
+
+ inside-group:
+ - meta_scope: meta.group.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: sql
+
+###[ COLUMN EXPRESSIONS ]######################################################
+
+ expect-column-declaration:
+ - include: column-declaration-list
+ - match: (?=\S)
+ set:
+ - maybe-column-modifier
+ - after-type
+ - expect-type
+ - column-name-declaration
+ - single-identifier
+
+ maybe-column-declaration-list:
+ - include: column-declaration-list
+ - include: else-pop
+
+ column-declaration-list:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-column-declaration-list
+
+ inside-column-declaration-list:
+ - meta_scope: meta.group.table-columns.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: column-modifiers
+ - include: expressions
+ - include: expect-column-declarations
+
+ expect-column-declarations:
+ - match: (?=\S)
+ push:
+ - maybe-column-modifier
+ - after-type
+ - expect-type
+ - column-name-declaration
+ - single-identifier
+
+ maybe-column-modifier:
+ - include: column-modifiers
+ - include: else-pop
+
+ column-modifiers:
+ - match: \b(?i:check)\b
+ scope: keyword.other.sql
+ - match: |-
+ \b(?xi:
+ (?: (?: fulltext | primary | unique ) \s+ )? key
+ | on \s+ (?: delete | update ) (?: \s+ cascade )?
+ | default
+ )\b
+ scope: storage.modifier.sql
+ - match: |-
+ \b(?xi:
+ foreign\s+key
+ )\b
+ scope: storage.modifier.sql
+ push: column-name-list
+ - match: \b(?i:unique)\b
+ scope: storage.modifier.sql
+ push: maybe-column-name-list
+ - match: \b(?i:references)\b
+ scope: storage.modifier.sql
+ push:
+ - maybe-column-name-list
+ - expect-table-name
+
+ maybe-column-name-list:
+ - include: column-name-list
+ - include: else-pop
+
+ column-name-list:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-column-name-list
+
+ column-name-lists:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ push: inside-column-name-list
+
+ inside-column-name-list:
+ - meta_scope: meta.group.table-columns.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: expressions-or-column-names
+
+###[ FUNCTION EXPRESSIONS ]####################################################
+
+ expect-function-parameters:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-function-parameters
+ - include: else-pop
+
+ inside-function-parameters:
+ - clear_scopes: 1
+ - meta_scope: meta.function.parameters.sql meta.group.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - include: comma-separators
+ - match: (?=\S)
+ push:
+ - expect-type
+ - expect-parameter-name
+ - maybe-parameter-modifier
+
+ expect-parameter-name:
+ - match: '{{simple_identifier}}'
+ scope: variable.parameter.sql
+ pop: 1
+ - include: else-pop
+
+ maybe-parameter-modifier:
+ - match: \b{{function_parameter_modifier}}\b
+ scope: storage.modifier.sql
+ pop: 1
+ - include: else-pop
+
+ expect-function-characteristics:
+ - meta_scope: meta.function.sql
+ - match: \b(?i:as|return)\b
+ scope: keyword.context.block.sql
+ pop: 1
+ - match: \b(?i:language)\b
+ scope: storage.modifier.sql
+ push: expect-function-language-name
+ - match: \b(?i:returns)\b
+ scope: keyword.other.ddl.sql
+ push: expect-type
+ - include: create-common-args
+
+ expect-function-language-name:
+ - match: '{{simple_identifier}}'
+ scope: constant.other.language.sql
+ pop: 1
+ - include: else-pop
+
+###[ USER MANAGEMENT EXPRESSIONS ]#############################################
+
+ grant:
+ - match: \b(?i:to)\b
+ scope: keyword.context.sql
+ push: expect-user-name
+ - include: comma-separators
+ - include: user-privileges
+ - include: pop-on-top-level-reserved-word
+
+ user-privileges:
+ - include: column-name-lists
+ - match: \b(?i:all(?:\s+privileges)?)\b
+ scope: constant.language.sql
+ - match: \b(?i:(?:alter|create|drop|grant|revoke)\s+{{ddl_target}})\b
+ scope: constant.language.sql
+ - match: \b(?i:select|insert|update|delete|truncate|execute)\b
+ scope: constant.language.sql
+
+###[ TABLE NAMES OR SUBQUERIES ]###############################################
+
+ table-name-or-subquery:
+ - meta_include_prototype: false
+ - include: table-subquery
+ - include: table-name-or-function-call
+
+ table-subquery:
+ - match: (?=\()
+ set:
+ - maybe-table-alias
+ - group
+
+ table-name-or-function-call:
+ - match: (?=\S)
+ pop: 1 # pop `table-name-or-subquery` before evaluating branches
+ branch_point: table-name-or-function-call
+ branch:
+ - table-name-not-function-call
+ - table-valued-function-call
+
+ table-name-not-function-call:
+ - meta_include_prototype: false
+ - match: ''
+ set:
+ - maybe-table-alias
+ - table-name-fail-if-function-call
+ - table-name
+ - single-identifier
+
+ table-name-fail-if-function-call:
+ - meta_include_prototype: false
+ - match: (?=\()
+ fail: table-name-or-function-call
+ - match: (?=\S)
+ pop: 1
+
+ table-valued-function-call:
+ - meta_include_prototype: false
+ - match: ''
+ set:
+ - maybe-table-alias
+ - function-call-arguments
+ - table-valued-function-name
+ - single-identifier
+
+ table-valued-function-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.table-valued-function-name.sql
+ - include: immediately-pop
+
+ maybe-table-alias:
+ - include: pop-on-top-level-reserved-word
+ - include: table-timespecs
+ - include: table-alias-expression
+ - include: expect-table-alias-name
+
+ table-timespecs:
+ - match: \b(?i:for\s+system_time)\b
+ scope: keyword.other.dml.sql
+ push: table-timespec-args
+
+ table-timespec-args:
+ - match: \b(?i:as\s+of|between|and|from|to)\b
+ scope: keyword.operator.logical.sql
+ push:
+ - table-timespec-expression
+ - table-timespec-type
+ - match: \b(?i:all)\b
+ scope: constant.other.sql
+ pop: 1
+ - include: else-pop
+
+ table-timespec-type:
+ - match: \b(?i:timestamp|transaction)\b
+ scope: storage.type.sql
+ set: else-pop
+ - include: else-pop
+
+ table-timespec-expression:
+ - include: expressions
+ - include: immediately-pop
+
+###[ TYPES ]###################################################################
+
+ expect-type:
+ - meta_include_prototype: false
+ - include: comments
+ - include: built-in-type
+ - include: expect-user-type
+
+ built-in-types:
+ - match: \b(?i:enum)\b
+ scope: storage.type.sql
+ push:
+ - after-type
+ - maybe-group
+ - match: |-
+ (?x)
+ \b(?: {{simple_types}} | {{types_with_optional_number}} )
+ (?: ((\()(\d+)(?:\s*(,)\s*(\d+))?(\)) | \b(?!\s*\() ) )
+ scope: storage.type.sql
+ captures:
+ 1: meta.parens.sql
+ 2: punctuation.definition.parens.begin.sql
+ 3: meta.number.integer.decimal.sql constant.numeric.value.sql
+ 4: punctuation.separator.sequence.sql
+ 5: meta.number.integer.decimal.sql constant.numeric.value.sql
+ 6: punctuation.definition.parens.end.sql
+ push: after-type
+ - match: \b{{type_modifiers}}\b
+ scope: storage.modifier.sql
+
+ built-in-type:
+ - match: \b(?i:enum)\b
+ scope: storage.type.sql
+ set:
+ - after-type
+ - maybe-group
+ - match: |-
+ (?x)
+ \b(?: {{simple_types}} | {{types_with_optional_number}} )
+ (?: ((\()(\d+)(?:\s*(,)\s*(\d+))?(\)) | \b(?!\s*\() ) )
+ scope: storage.type.sql
+ captures:
+ 1: meta.parens.sql
+ 2: punctuation.definition.parens.begin.sql
+ 3: meta.number.integer.decimal.sql constant.numeric.value.sql
+ 4: punctuation.separator.sequence.sql
+ 5: meta.number.integer.decimal.sql constant.numeric.value.sql
+ 6: punctuation.definition.parens.end.sql
+ set: after-type
+
+ expect-user-type:
+ - match: (?=\S)
+ set: [maybe-group, after-type, inside-user-type]
+
+ inside-user-type:
+ # note: may contain foreign variable interpolation
+ - meta_scope: support.type.sql
+ - match: '{{simple_identifier_break}}'
+ pop: 1
+
+ after-type:
+ - match: \b{{type_modifiers}}\b
+ scope: storage.modifier.sql
+ pop: 1
+ - include: assignment-operators
+ - include: else-pop
+
+###[ IDENTIFIERS ]#############################################################
+
+ expect-table-alias-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [table-alias-name, single-identifier]
+
+ expect-column-alias-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [column-alias-name, single-identifier]
+
+ table-alias-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.alias.table.sql
+ - include: immediately-pop
+
+ column-alias-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.alias.column.sql
+ - include: immediately-pop
+
+ expect-column-names:
+ - match: (?=\S)
+ push: [maybe-operator, column-name, single-identifier]
+
+ expect-column-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [column-name, single-identifier]
+
+ column-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.column-name.sql
+ - include: immediately-pop
+
+ expect-column-name-declaration:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [column-name-declaration, single-identifier]
+
+ column-name-declaration:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.column-name.sql variable.other.member.declaration.sql
+ - include: immediately-pop
+
+ expect-constraint-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - match: (?=(?i:check|foreign|primary|unique|index|key|using|with)\b)
+ pop: 1
+ - include: comments
+ - match: (?=\S)
+ set: [constraint-name, single-identifier]
+
+ constraint-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.constraint-name.sql
+ - include: immediately-pop
+
+ expect-database-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [database-creation-name, single-identifier]
+
+ database-creation-name:
+ - meta_include_prototype: false
+ - meta_content_scope: entity.name.struct.database.sql
+ - include: immediately-pop
+
+ expect-database-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [database-name, single-identifier]
+
+ database-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.database-name.sql
+ - include: immediately-pop
+
+ expect-event-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [event-creation-name, single-identifier]
+
+ event-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.event.sql
+ - include: immediately-pop
+
+ expect-event-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [event-name, single-identifier]
+
+ event-name:
+ - meta_include_prototype: false
+ - meta_scope: meta.event-name.sql
+ - include: immediately-pop
+
+ expect-index-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [index-creation-name, single-identifier]
+
+ index-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.struct.index.sql
+ - include: immediately-pop
+
+ expect-index-names:
+ - match: (?=\S)
+ push: [index-name, single-identifier]
+
+ expect-index-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [index-name, single-identifier]
+
+ index-name:
+ - meta_include_prototype: false
+ - meta_scope: meta.index-name.sql
+ - include: immediately-pop
+
+ expect-function-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [procedure-creation-name, single-identifier]
+
+ expect-partition-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [partition-creation-name, single-identifier]
+
+ partition-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.struct.partition.sql
+ - include: immediately-pop
+
+ expect-partition-names:
+ - match: (?=\S)
+ push: [partition-name, single-identifier]
+
+ expect-partition-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [partition-name, single-identifier]
+
+ partition-name:
+ - meta_include_prototype: false
+ - meta_scope: meta.partition-name.sql
+ - include: immediately-pop
+
+ procedure-creation-name:
+ - meta_include_prototype: false
+ - meta_content_scope: entity.name.function.sql
+ - include: immediately-pop
+
+ expect-function-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [procedure-name, single-identifier]
+
+ procedure-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.procedure-name.sql
+ - include: immediately-pop
+
+ expect-table-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [table-creation-name, single-identifier]
+
+ table-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.struct.table.sql
+ - include: immediately-pop
+
+ expect-table-names:
+ - match: (?=\S)
+ push: [table-name, single-identifier]
+
+ expect-table-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [table-name, single-identifier]
+
+ table-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.table-name.sql
+ - include: immediately-pop
+
+ expect-user-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - include: built-in-user-function-call
+ - match: (?=\S)
+ set: [user-name, single-identifier]
+
+ user-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.username.sql
+ - include: immediately-pop
+
+ expect-user-name-declaration:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [user-name-declaration, single-identifier]
+
+ user-name-declaration:
+ - meta_include_prototype: false
+ - meta_content_scope: entity.name.user.sql
+ - include: immediately-pop
+
+ expect-type-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [type-creation-name, single-identifier]
+
+ type-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.type.cql
+ - include: immediately-pop
+
+ expect-other-creation-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [other-creation-name, single-identifier]
+
+ other-creation-name:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.struct.other.sql
+ - include: immediately-pop
+
+ expect-other-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [other-name, single-identifier]
+
+ other-name:
+ - meta_include_prototype: false
+ - meta_scope: meta.other-name.sql
+ - include: immediately-pop
+
+ single-identifier:
+ - meta_include_prototype: false
+ - include: pop-on-top-level-reserved-word
+ - match: ''
+ set:
+ - maybe-identifier-accessor
+ - identifier-part
+
+ maybe-identifier-accessor:
+ - meta_include_prototype: false
+ - match: \s*(\.)\s*(\*)
+ captures:
+ 1: punctuation.accessor.dot.sql
+ 2: constant.other.wildcard.asterisk.sql
+ pop: 1
+ - match: \s*(\.)
+ captures:
+ 1: punctuation.accessor.dot.sql
+ set: single-identifier
+ - include: immediately-pop
+
+ identifier-part:
+ - meta_include_prototype: false
+ - include: backtick-quoted-identifier-part
+ - include: double-quoted-identifier-part
+ - include: single-quoted-identifier-part
+ - include: simple-identifier-part
+
+ backtick-quoted-identifier-part:
+ - match: \`
+ scope: punctuation.definition.identifier.begin.sql
+ set: inside-backtick-quoted-identifier-part
+
+ inside-backtick-quoted-identifier-part:
+ # note: may contain foreign variable interpolation
+ - match: \`
+ scope: punctuation.definition.identifier.end.sql
+ pop: 1
+
+ double-quoted-identifier-part:
+ - match: \"
+ scope: punctuation.definition.identifier.begin.sql
+ set: inside-double-quoted-identifier-part
+
+ inside-double-quoted-identifier-part:
+ # note: may contain foreign variable interpolation
+ - match: \"
+ scope: punctuation.definition.identifier.end.sql
+ pop: 1
+
+ single-quoted-identifier-part:
+ - match: \'
+ scope: punctuation.definition.identifier.begin.sql
+ set: inside-single-quoted-identifier-part
+
+ inside-single-quoted-identifier-part:
+ # note: may contain foreign variable interpolation
+ - match: \'
+ scope: punctuation.definition.identifier.end.sql
+ pop: 1
+
+ simple-identifier-part:
+ - match: (?=\S)
+ set: inside-simple-identifier-part
+
+ inside-simple-identifier-part:
+ # note: may contain foreign variable interpolation
+ - match: '{{simple_identifier_break}}'
+ pop: 1
+
+ wildcard-identifiers:
+ - match: \*
+ scope: constant.other.wildcard.asterisk.sql
+
+###[ LITERALS ]################################################################
+
+ literals-and-variables:
+ - include: built-in-types
+ - include: constants
+ - include: numbers
+ - include: strings
+
+ constants:
+ - match: \b(?i:null)\b
+ scope: constant.language.null.sql
+
+ booleans:
+ - match: \b(?i:true)\b
+ scope: constant.language.boolean.true.sql
+ - match: \b(?i:false)\b
+ scope: constant.language.boolean.false.sql
+
+ numbers:
+ - match: \b\d+(\.)\d+\b
+ scope: meta.number.float.decimal.sql constant.numeric.value.sql
+ captures:
+ 1: punctuation.separator.decimal.sql
+ - match: \b\d+\b
+ scope: meta.number.integer.decimal.sql constant.numeric.value.sql
+
+ strings:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ push: inside-single-quoted-string
+
+ inside-single-quoted-string:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.sql string.quoted.single.sql
+ - match: \'\'
+ scope: constant.character.escape.sql
+ - match: \'
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - include: string-escapes
+
+ string-escapes:
+ - match: '{{string_escape}}'
+ scope: constant.character.escape.sql
+
+###[ LIKE EXPRESSIONS ]########################################################
+
+ like-expressions:
+ - match: \b(?i:like)\b
+ scope: keyword.operator.logical.sql
+ branch_point: like-expressions
+ branch:
+ - like-string-not-followed-by-escape
+ - like-string-followed-by-escape-slash
+ - like-string-followed-by-escape-caret
+ - like-string-followed-by-escape-hash
+ - like-string-followed-by-unknown-escape
+
+ like-string-not-followed-by-escape:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-fail
+ - inside-like-single-quoted-string
+ - include: else-pop
+
+ like-string-followed-by-escape-slash:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-character-slash
+ - like-escape
+ - inside-like-single-quoted-string-slash-escape
+ - include: else-pop
+
+ like-string-followed-by-escape-caret:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-character-caret
+ - like-escape
+ - inside-like-single-quoted-string-caret-escape
+ - include: else-pop
+
+ like-string-followed-by-escape-hash:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-character-hash
+ - like-escape
+ - inside-like-single-quoted-string-hash-escape
+ - include: else-pop
+
+ like-string-followed-by-unknown-escape:
+ - match: \'
+ scope: punctuation.definition.string.begin.sql
+ set:
+ - like-escape-character-any
+ - like-escape
+ - inside-like-single-quoted-string
+ - include: else-pop
+
+ inside-like-single-quoted-string-slash-escape:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.like.sql string.quoted.single.sql
+ - match: \\.
+ scope: constant.character.escape.sql
+ - include: inside-like-single-quoted-string
+
+ inside-like-single-quoted-string-caret-escape:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.like.sql string.quoted.single.sql
+ - match: \^.
+ scope: constant.character.escape.sql
+ - include: inside-like-single-quoted-string
+
+ inside-like-single-quoted-string-hash-escape:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.like.sql string.quoted.single.sql
+ - match: '#.'
+ scope: constant.character.escape.sql
+ - include: inside-like-single-quoted-string
+
+ inside-like-single-quoted-string:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.like.sql string.quoted.single.sql
+ - match: \'
+ scope: punctuation.definition.string.end.sql
+ pop: 1
+ - match: '%'
+ scope: constant.other.wildcard.percent.sql
+ - match: '_'
+ scope: constant.other.wildcard.underscore.sql
+
+ like-else-fail:
+ - match: (?=\S)
+ fail: like-expressions
+
+ like-escape-fail:
+ - match: \b(?i:escape)\b
+ fail: like-expressions
+ - include: else-pop
+
+ like-escape:
+ - match: \b(?i:escape)\b
+ scope: keyword.operator.word.sql
+ pop: 1
+ - include: else-pop
+
+ like-escape-character-any:
+ - match: (\')([^'])(\')
+ scope: meta.string.escape.sql string.quoted.single.sql
+ captures:
+ 1: punctuation.definition.string.begin.sql
+ 2: constant.character.escape.sql
+ 3: punctuation.definition.string.end.sql
+ pop: 1
+ - include: else-pop
+
+ like-escape-character-caret:
+ - match: (\')(\^)(\')
+ scope: meta.string.escape.sql string.quoted.single.sql
+ captures:
+ 1: punctuation.definition.string.begin.sql
+ 2: constant.character.escape.sql
+ 3: punctuation.definition.string.end.sql
+ pop: 1
+ - include: like-else-fail
+
+ like-escape-character-slash:
+ - match: (\')(\\)(\')
+ scope: meta.string.escape.sql string.quoted.single.sql
+ captures:
+ 1: punctuation.definition.string.begin.sql
+ 2: constant.character.escape.sql
+ 3: punctuation.definition.string.end.sql
+ pop: 1
+ - include: like-else-fail
+
+ like-escape-character-hash:
+ - match: (\')(#)(\')
+ scope: meta.string.escape.sql string.quoted.single.sql
+ captures:
+ 1: punctuation.definition.string.begin.sql
+ 2: constant.character.escape.sql
+ 3: punctuation.definition.string.end.sql
+ pop: 1
+ - include: like-else-fail
+
+###[ OPERATORS ]###############################################################
+
+ maybe-condition:
+ - meta_include_prototype: false
+ - include: conditions
+ - include: else-pop
+
+ conditions:
+ - match: \b(?i:if)\b
+ scope: keyword.control.conditional.if.sql
+ - include: logical-operators
+
+ maybe-operator:
+ - match: '<=>|[!<>]?=|<>|<|>'
+ scope: keyword.operator.comparison.sql
+ pop: 1
+ - match: '[-+/*]'
+ scope: keyword.operator.arithmetic.sql
+ pop: 1
+ - match: \b(?i:and|or|having|exists|between|in|not|is)\b
+ scope: keyword.operator.logical.sql
+ pop: 1
+ - include: else-pop
+
+ operators:
+ - match: '<=>|[!<>]?=|<>|<|>'
+ scope: keyword.operator.comparison.sql
+ - match: '[-+/*]'
+ scope: keyword.operator.arithmetic.sql
+ - include: logical-operators
+
+ assignment-operators:
+ - match: '='
+ scope: keyword.operator.assignment.sql
+
+ logical-operators:
+ - match: \b(?i:and|or|having|exists|between|in|not|is)\b
+ scope: keyword.operator.logical.sql
+
+ comma-separators:
+ - match: ','
+ scope: punctuation.separator.sequence.sql
+
+ statement-terminators:
+ - match: ';'
+ scope: punctuation.terminator.statement.sql
+
+###[ ILLEGALS ]################################################################
+
+ illegal-stray-brackets:
+ - match: \]
+ scope: invalid.illegal.stray.sql
+
+ illegal-stray-parens:
+ - match: \)
+ scope: invalid.illegal.stray.sql
+
+###[ PROTOTYPES ]##############################################################
+
+ else-pop:
+ - match: (?=\S)
+ pop: 1
+
+ immediately-pop:
+ - match: ''
+ pop: 1
+
+ pop-on-top-level-reserved-word:
+ - match: (?=[;)}]|\b(?:{{toplevel_reserved}}|{{additional_toplevel_reserved}})\b)
+ pop: 1
diff --git a/SQL/SQL.sublime-syntax b/SQL/SQL.sublime-syntax
index 262738ed9f..8a9c5e51f9 100644
--- a/SQL/SQL.sublime-syntax
+++ b/SQL/SQL.sublime-syntax
@@ -2,6 +2,9 @@
---
name: SQL
scope: source.sql
+version: 2
+
+extends: Packages/SQL/MySQL.sublime-syntax
file_extensions:
- sql
@@ -12,382 +15,3 @@ first_line_match: |-
(?xi:
^ \s* -- .*? -\*- .*? \bsql\b .*? -\*- # editorconfig
)
-
-variables:
- end_identifier: (?=[ \t]*(?:[^\w'"`. \t]|$))
-
-contexts:
- prototype:
- - include: comments
- main:
- - match: |-
- (?xi)
- \b(create(?:\s+or\s+replace)?)\s+
- (aggregate|conversion|database|domain|function|group|((?:fulltext|spatial|unique)\s+)?index|language|operator class|operator|procedure|rule|schema|sequence|table(?:space)?|trigger|type|user|view)
- \b\s*
- scope: meta.create.sql
- captures:
- 1: keyword.other.create.sql
- 2: keyword.other.sql
- push: create-condition
- - match: (?i:\s*\b(drop)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|procedure|rule|schema|sequence|table|tablespace|trigger|type|user|view))
- scope: meta.drop.sql
- captures:
- 1: keyword.other.create.sql
- 2: keyword.other.sql
- push: drop-condition
- - match: (?i:\s*(drop)\s+(table)\s+(\w+)(\s+cascade)?\b)
- scope: meta.drop.sql
- captures:
- 1: keyword.other.create.sql
- 2: keyword.other.table.sql
- 3: entity.name.function.sql
- 4: keyword.other.cascade.sql
- - match: (?i:\s*\b(alter)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|procedure|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+)
- scope: meta.alter.sql
- captures:
- 1: keyword.other.create.sql
- 2: keyword.other.table.sql
- - match: (?i:\s*\b(add)\s+(column|constraint|fulltext\s+(index|key)|index|spatial\s+(index|key)))
- scope: meta.add.sql
- captures:
- 1: keyword.other.add.sql
- 2: keyword.other.sql
- - match: |-
- (?xi)
-
- # normal stuff, capture 1
- \b(bigint|bigserial|bit|bool|boolean|box|bytea|cidr|circle|date|datetime|double\s+precision|enum|inet|int|integer|line|longtext|lseg|macaddr|money|ntext|oid|path|point|polygon|real|serial|smallint|sysdate|sysname|text|tinytext)\b
-
- # numeric suffix, capture 2 + 3i
- |\b(bit\svarying|character\s+(?:varying)?|tinyint|var\schar|float|interval)\((\d+)\)
-
- # optional numeric suffix, capture 4 + 5i
- |\b(char|number|nvarchar|varbinary|varchar\d?)\b(?:\((\d+)\))?
-
- # special case, capture 6 + 7i + 8i
- |\b(numeric|decimal)\b(?:\((\d+),(\d+)\))?
-
- # special case, captures 9, 10i, 11
- |\b(times?)\b(?:\((\d+)\))?(\swith(?:out)?\s+time\s+zone\b)?
-
- # special case, captures 12, 13, 14i, 15
- |\b(timestamp)(?:(s|tz))?\b(?:\((\d+)\))?(\s(with|without)\s+time\s+zone\b)?
-
-
- captures:
- 1: storage.type.sql
- 2: storage.type.sql
- 3: constant.numeric.sql
- 4: storage.type.sql
- 5: constant.numeric.sql
- 6: storage.type.sql
- 7: constant.numeric.sql
- 8: constant.numeric.sql
- 9: storage.type.sql
- 10: constant.numeric.sql
- 11: storage.type.sql
- 12: storage.type.sql
- 13: storage.type.sql
- 14: constant.numeric.sql
- 15: storage.type.sql
- - match: (?i:\b(((?:foreign|fulltext|primary|unique)\s+)?key|references|on\sdelete(\s+cascade)?|on\supdate(\s+cascade)?|check|constraint|default)\b)
- scope: storage.modifier.sql
- - match: \b\d+\b
- scope: constant.numeric.sql
- - match: (?i:\bfalse\b)
- scope: constant.language.boolean.false.sql
- - match: (?i:\btrue\b)
- scope: constant.language.boolean.true.sql
- - match: (?i:\b(null)\b)
- scope: constant.language.null.sql
- - match: (?i:\b(select(\s+(distinct|top))?|insert(\s+(ignore\s+)?into)?|update|delete|truncate|from|set|where|group\s+by|with|case|when|then|else|end|union(\s+all)?|using|order\s+by|limit|(inner|cross)\s+join|join|straight_join|(left|right)(\s+outer)?\s+join|natural(\s+(left|right)(\s+outer)?)?\s+join)\b)
- scope: keyword.other.DML.sql
- - include: logical-operators
- - match: (?i:\blike\b)
- scope: keyword.operator.logical.sql
- branch_point: like-strings-branch
- branch:
- - like-string-not-followed-by-escape
- - like-string-followed-by-escape-slash
- - like-string-followed-by-escape-caret
- - like-string-followed-by-unknown-escape
- - match: (?i:\bvalues\b)
- scope: keyword.other.DML.II.sql
- - match: (?i:\b(begin(\s+work)?|start\s+transaction|commit(\s+work)?|rollback(\s+work)?)\b)
- scope: keyword.other.LUW.sql
- - match: (?i:\b(grant(\swith\sgrant\soption)?|revoke)\b)
- scope: keyword.other.authorization.sql
- - match: (?i:\s*\b(comment\s+on\s+(table|column|aggregate|constraint|database|domain|function|index|operator|rule|schema|sequence|trigger|type|view))\s+.*?\s+(is)\s+)
- scope: keyword.other.object-comments.sql
- - match: (?i)\bas\b
- scope: keyword.operator.assignment.alias.sql
- - match: (?i)\b(asc|desc)\b
- scope: keyword.other.order.sql
- - match: \*
- scope: constant.other.wildcard.asterisk.sql
- - match: "<=>|[!<>]?=|<>|<|>"
- scope: keyword.operator.comparison.sql
- - match: '-|\+|/'
- scope: keyword.operator.arithmetic.sql
- - match: \|\|
- scope: keyword.operator.concatenation.sql
- - match: (?i)\b(CURRENT_(DATE|TIME(STAMP)?|USER)|(SESSION|SYSTEM)_USER)\b
- comment: List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html
- scope: support.function.scalar.sql
- - match: (?i)\b(AVG|COUNT|MIN|MAX|SUM)(?=\s*\()
- comment: List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html
- scope: support.function.aggregate.sql
- - match: (?i)\b(CONCATENATE|CONVERT|LOWER|SUBSTRING|TRANSLATE|TRIM|UPPER)\b
- scope: support.function.string.sql
- - match: \b(\w+?)\.(\w+)\b
- captures:
- 1: constant.other.database-name.sql
- 2: constant.other.table-name.sql
- - include: strings
- - include: regexps
- - match: (\()(\))
- comment: Allow for special ↩ behavior
- scope: meta.block.sql
- captures:
- 1: punctuation.section.scope.begin.sql
- 2: punctuation.section.scope.end.sql
- - match: (?i)\bon\b
- scope: keyword.operator.word.sql
- - match: ','
- scope: punctuation.separator.sequence.sql
- - match: ';'
- scope: punctuation.terminator.statement.sql
- comments:
- - meta_include_prototype: false
- - match: '--'
- scope: punctuation.definition.comment.sql
- push: inside-double-dash-comment
- - match: '#'
- scope: punctuation.definition.comment.sql
- push: inside-number-sign-comment
- - match: /\*
- scope: punctuation.definition.comment.begin.sql
- push: inside-comment-block
- inside-double-dash-comment:
- - meta_include_prototype: false
- - meta_scope: comment.line.double-dash.sql
- - match: \n
- pop: true
- inside-number-sign-comment:
- - meta_include_prototype: false
- - meta_scope: comment.line.number-sign.sql
- - match: \n
- pop: true
- inside-comment-block:
- - meta_include_prototype: false
- - meta_scope: comment.block.sql
- - match: \*/
- scope: punctuation.definition.comment.end.sql
- pop: true
- - match: ^\s*(\*)(?!/)
- captures:
- 1: punctuation.definition.comment.sql
- regexps:
- - match: /(?=\S.*/)
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.regexp.sql
- - match: /
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-interpolation
- - match: \\/
- scope: constant.character.escape.slash.sql
- - match: '%r\{'
- comment: We should probably handle nested bracket pairs!?! -- Allan
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.regexp.modr.sql
- - match: '\}'
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-interpolation
- string-escape:
- - meta_include_prototype: false
- - match: \\.
- scope: constant.character.escape.sql
- string-interpolation:
- - meta_include_prototype: false
- - match: '(#\{)([^\}]*)(\})'
- scope: string.interpolated.sql
- captures:
- 1: punctuation.definition.string.begin.sql
- 3: punctuation.definition.string.end.sql
- strings:
- - match: "'"
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.quoted.single.sql
- - match: "''"
- scope: constant.character.escape.sql
- - match: "'"
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-escape
- - match: "`"
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.quoted.other.backtick.sql
- - match: "`"
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-escape
- - match: '"'
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.quoted.double.sql
- - match: '""'
- scope: constant.character.escape.sql
- - match: '"'
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-interpolation
- - match: '%\{'
- scope: punctuation.definition.string.begin.sql
- push:
- - meta_include_prototype: false
- - meta_scope: string.other.quoted.brackets.sql
- - match: '\}'
- scope: punctuation.definition.string.end.sql
- pop: true
- - include: string-interpolation
- identifier-create:
- - meta_content_scope: meta.toc-list.full-identifier.sql
- - match: '(?:(\w+)|''([^'']+)''|"([^"]+)"|`([^`]+)`){{end_identifier}}'
- scope: meta.toc-list.full-identifier.sql
- captures:
- 1: entity.name.function.sql
- 2: entity.name.function.sql
- 3: entity.name.function.sql
- 4: entity.name.function.sql
- pop: true
- # Schema identifiers
- - match: (?:\w+|'[^']+'|"[^"]+"|`[^`]+`)\s*(\.)
- captures:
- 1: punctuation.accessor.dot.sql
- # Handle situations where the schema and .
- - match: '{{end_identifier}}'
- pop: true
- create-condition:
- - include: dml-condition
- - match: (?=\S)
- set: identifier-create
- drop-condition:
- - include: dml-condition
- - match: (?=\S)
- pop: true
- dml-condition:
- - match: (?i:\b(if)\b)
- scope: keyword.control.flow.sql
- - include: logical-operators
- logical-operators:
- - match: (?i:\b(and|or|having|exists|between|in|not|is)\b)
- scope: keyword.operator.logical.sql
- like-string-not-followed-by-escape:
- - match: \'
- scope: punctuation.definition.string.begin.sql
- set: [like-escape-fail, inside-like-single-quoted-string]
- - match: (?=\S)
- pop: true
- like-string-followed-by-escape-slash:
- - match: \'
- scope: punctuation.definition.string.begin.sql
- set: [like-escape-character-slash, like-escape-pop, inside-like-single-quoted-string-slash-escape]
- - match: (?=\S)
- pop: true
- like-string-followed-by-escape-caret:
- - match: \'
- scope: punctuation.definition.string.begin.sql
- set: [like-escape-character-caret, like-escape-pop, inside-like-single-quoted-string-caret-escape]
- - match: (?=\S)
- pop: true
- like-string-followed-by-unknown-escape:
- - match: \'
- scope: punctuation.definition.string.begin.sql
- set: [like-escape-character-any, like-escape-pop, inside-like-single-quoted-string]
- - match: (?=\S)
- pop: true
- inside-like-single-quoted-string-slash-escape:
- - meta_include_prototype: false
- - meta_scope: meta.string.like.sql string.quoted.single.sql
- - match: \\.
- scope: constant.character.escape.sql
- - include: inside-like-single-quoted-string
- inside-like-single-quoted-string-caret-escape:
- - meta_include_prototype: false
- - meta_scope: meta.string.like.sql string.quoted.single.sql
- - match: \^.
- scope: constant.character.escape.sql
- - include: inside-like-single-quoted-string
- inside-like-single-quoted-string:
- - meta_include_prototype: false
- - meta_scope: meta.string.like.sql string.quoted.single.sql
- - match: \'
- scope: punctuation.definition.string.end.sql
- pop: true
- - match: |-
- (?x)
- (\[)(\^)?
- (?:.|[^]'-]+?)
- (?:(-)[^]'-]*)?
- (\])
- scope: meta.set.like.sql
- captures:
- 1: keyword.control.set.begin.sql
- 2: keyword.control.set.negation.sql
- 3: constant.other.range.sql
- 4: keyword.control.set.end.sql
- - match: '[%_]'
- scope: keyword.operator.wildcard.sql
- like-escape-fail:
- - match: (?i:\bescape\b)
- fail: like-strings-branch
- - match: (?=\S)
- pop: true
- like-escape-pop:
- - match: (?i:\bescape\b)
- scope: keyword.operator.word.sql
- pop: true
- - match: (?=\S)
- pop: true
- like-escape-character-any:
- - match: (\')([^'])(\')
- captures:
- 0: meta.string.escape.sql string.quoted.single.sql
- 1: punctuation.definition.string.begin.sql
- 2: constant.character.escape.sql
- 3: punctuation.definition.string.end.sql
- pop: true
- - match: (?=\S)
- pop: true
- like-escape-character-caret:
- - match: (\')(\^)(\')
- captures:
- 0: meta.string.escape.sql string.quoted.single.sql
- 1: punctuation.definition.string.begin.sql
- 2: constant.character.escape.sql
- 3: punctuation.definition.string.end.sql
- pop: true
- - match: (?=\S)
- fail: like-strings-branch
- like-escape-character-slash:
- - match: (\')(\\)(\')
- captures:
- 0: meta.string.escape.sql string.quoted.single.sql
- 1: punctuation.definition.string.begin.sql
- 2: constant.character.escape.sql
- 3: punctuation.definition.string.end.sql
- pop: true
- - match: (?=\S)
- fail: like-strings-branch
diff --git a/SQL/Symbol List.tmPreferences b/SQL/Symbol List.tmPreferences
new file mode 100644
index 0000000000..0c25d4e279
--- /dev/null
+++ b/SQL/Symbol List.tmPreferences
@@ -0,0 +1,12 @@
+
+
+
+ scope
+ source.sql entity.name.struct
+ settings
+
+ showInSymbolList
+ 1
+
+
+
diff --git a/SQL/TSQL.sublime-syntax b/SQL/TSQL.sublime-syntax
new file mode 100644
index 0000000000..4e3df8fc45
--- /dev/null
+++ b/SQL/TSQL.sublime-syntax
@@ -0,0 +1,1058 @@
+%YAML 1.2
+---
+name: T-SQL
+scope: source.sql.tsql
+version: 2
+
+extends: Packages/SQL/SQL (basic).sublime-syntax
+
+variables:
+ string_escape: (?:'')
+ simple_identifier_break: (?![\w#@])
+
+ additional_toplevel_reserved: |-
+ (?xi: backup | begin | break | bulk | continue | declare | else | end
+ | exec(?:ute)? | for | go | if | insert | merge | on | print | raiserror
+ | return | throw | use | waitfor | when | while | with )
+
+ identifier_for_lookahead: |-
+ (?x:
+ (?:(?:\b\w+|\[[^]]+\])\.)*
+ (?:\b\w+|\[[^]]+\])
+ )
+
+ ddl_target_function: |-
+ (?xi: proc(?:edure)? | func(?:tion)? )
+
+ # types
+
+ enclosed_type_begin: \[
+ enclosed_type_end: \]
+
+ simple_types: |-
+ (?xi: bigint | bit | float | int | real | smallint | tinyint
+ | date | datetime | datetime2 | datetimeoffset | smalldatetime | time
+ | geometry | hierarchyid | image | n?text | rowversion | sql_variant
+ | sysname | uniqueidentifier | xml )
+ types_with_optional_number: |-
+ (?xi: n?(?:var)?char | binary | varbinary | decimal | money | numeric )
+
+ builtin_user_functions: |-
+ (?xi: (?: current_ | session_ | system_ )? user )
+
+contexts:
+
+ sql:
+ - meta_prepend: true
+ - include: declare-statements
+
+###[ DECLARE STATEMENTS ]######################################################
+
+ declare-statements:
+ - match: \b(?i:declare)\b
+ scope: keyword.declaration.variable.sql
+ push: inside-declaration
+
+ inside-declaration:
+ - match: '{{simple_identifier}}(?=\s+(?i:cursor)\b)'
+ scope: meta.cursor-name.sql
+ pop: 1
+ - match: (@){{simple_identifier}}
+ scope: variable.other.readwrite.declaration.tsql
+ captures:
+ 1: punctuation.definition.variable.tsql
+ push: expect-type
+ - match: ','
+ scope: punctuation.separator.sequence.tsql
+ - include: else-pop
+
+###[ DDL CREATE STATEMENTS ]###################################################
+
+ create-statements:
+ - match: \b(?i:create(?:\s+or\s+alter)?)\b
+ scope: keyword.other.ddl.sql
+ push:
+ - create-meta
+ - create-target
+
+ create-target:
+ - meta_prepend: true
+ # modifiers
+ - match: \b(?i:unique|clustered|nonclustered)\b
+ scope: keyword.other.ddl.sql
+ - include: create-sequence
+
+ expect-function-characteristics:
+ - meta_prepend: true
+ - include: target-options
+
+ create-other-args:
+ - meta_prepend: true
+ - match: \b(?i:without\s+\w+)\b
+ scope: storage.modifier.tsql
+
+ create-sequence:
+ - match: \b(?i:sequence)\b
+ scope: keyword.other.ddl.sql
+ set:
+ - create-sequence-args
+ - expect-other-creation-name
+ - create-other-condition
+
+ create-sequence-args:
+ - match: \b(?i:as)\b
+ scope: keyword.context.block.sql
+ push:
+ - expect-type
+ - match: \b(?i:START\s+WITH|INCREMENT\s+BY|(?:NO\s+)?(?:MINVALUE|MAXVALUE|CYCLE|CACHE))\b
+ scope: keyword.other.ddl.basic
+ - include: create-common-args
+
+ create-table-args:
+ - meta_prepend: true
+ - match: (?=\b(?i:as)\b)
+ pop: 1
+
+###[ DDL STATEMENT PROTOTYPES ]################################################
+
+ alter-common:
+ - meta_prepend: true
+ - include: with-options
+ - match: \b(?i:(add)\s+(member))\b
+ captures:
+ 1: keyword.other.ddl.sql
+ 2: keyword.other.ddl.sql
+ push:
+ - expect-user-name
+
+ alter-table-args:
+ - meta_prepend: true
+ - match: \b(?i:with\s+check\b)
+ scope: keyword.other.ddl.tsql
+
+ target-options:
+ - meta_prepend: true
+ - include: with-table-options
+
+###[ DML STATEMENTS ]##########################################################
+
+ dml-statements:
+ - meta_append: true
+ - match: \b(?i:bulk\s+insert)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:insert)\b
+ scope: keyword.other.dml.sql
+ push: expect-table-name
+ - match: \b(?i:into)\b(?!\s*@)
+ scope: keyword.other.dml.tsql
+ push: expect-table-name
+ - match: \b(?i:into)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:off)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:for\s+xml)\b
+ scope: keyword.other.tsql
+ push: for-xml
+ - match: \b(?i:option)\b
+ scope: keyword.other.dml.tsql
+ push: maybe-with-group
+ - match: \b(?i:open|fetch(?:(?:\s+next)?\s+from)?|close|deallocate)\b
+ scope: keyword.other.sql
+ push: expect-cursor-name
+ - match: \b(?i:merge(?:\s+into)?)\b
+ scope: keyword.other.tsql
+ push:
+ - maybe-table-alias
+ - expect-table-name
+ - match: \b(?i:using)\b # note: maybe valid only in merge statements
+ scope: keyword.context.resource.tsql
+ push: table-name-or-subquery
+ - match: \b(?i:on)\b
+ scope: keyword.control.conditional.sql
+ # - match: \b(?i:set)\b
+ # scope: keyword.other.dml.tsql
+ # push: maybe-transaction-isolation-level
+ - include: top
+
+ dml-delete:
+ - meta_prepend: true
+ - include: top
+
+ dml-update:
+ - meta_prepend: true
+ - include: top
+
+ join-expressions:
+ - meta_append: true
+ - match: \b(?i:(?:(?:cross|outer)\s+)?apply)\b
+ scope: keyword.other.dml.sql
+ push: table-name-or-subquery
+
+ top:
+ - match: (?i)\b(top)\b(?:\s*(?:(\()\s*)?(\d+)(?:\s*(\)))?(?:\s+(percent\b))?)?
+ captures:
+ 1: keyword.other.dml.tsql
+ 2: meta.group.tsql punctuation.section.parens.begin.tsql
+ 3: meta.group.tsql meta.number.integer.decimal.tsql constant.numeric.value.tsql
+ 4: meta.group.tsql punctuation.section.parens.end.tsql
+ 5: keyword.other.dml.tsql
+
+ for-xml:
+ - match: \b(?i:raw|auto|elements|root|path)\b
+ scope: keyword.other.tsql
+ - match: \b(?:XSINIL|XMLSCHEMA)\b # case sensitive?! TODO: need to check
+ scope: keyword.other.tsql
+ - match: (?=\))
+ pop: 1
+ - include: expressions
+ - include: else-pop
+
+###[ DML SET STATEMENTS ]######################################################
+
+ set-target:
+ - meta_prepend: true
+ - match: \b(?i:nocount|ansi_nulls|quoted_identifier|xact_abort|ansi_warnings|noexec|showplan_(?:all|text|xml))\b
+ scope: constant.language.switch.tsql
+ - match: \b(?i:identity_insert)\b
+ scope: constant.language.switch.tsql
+ push: expect-table-name
+ - match: \b(?i:transaction\s+isolation\s+level)\b
+ scope: constant.language.switch.tsql
+ set: transaction-isolation-level
+ - match: \b(?i:deadlock_priority)\b
+ scope: constant.language.switch.tsql
+ set: deadlock-priority
+ - include: onoff-constants
+ - include: variables
+ - include: augmented-assignment-operators
+ - include: operators
+ - match: ','
+ scope: punctuation.separator.sequence.tsql
+
+ transaction-isolation-level:
+ - match: \b(?i:READ\s+UNCOMMITTED|READ\s+COMMITTED|REPEATABLE\s+READ|SNAPSHOT|SERIALIZABLE)\b
+ scope: constant.language.tsql
+ pop: 1
+ - match: (?=\S)
+ pop: 1
+
+ deadlock-priority:
+ - match: \b(?i:low|normal|high)\b
+ scope: constant.language.tsql
+ pop: 1
+ - include: else-pop
+
+###[ OTHER STATEMENTS ]########################################################
+
+ other-statements:
+ - meta_prepend: true
+ # context keywords
+ - include: cte-with
+ - match: \b(?i:(?:begin|commit|rollback|save)\s+tran(?:saction)?)\b
+ scope: keyword.context.tsql
+ - match: \b(?i:use)\b
+ scope: keyword.context.tsql
+ push: expect-database-name
+ # control flow keywords
+ - match: \b(?i:if)\b
+ scope: keyword.control.conditional.if.tsql
+ - match: \b(?i:else)\b
+ scope: keyword.control.conditional.else.tsql
+ - match: \b(?i:begin|end)\s+(?i:try|catch)\b
+ scope: keyword.control.exception.tsql
+ - match: \b(?i:while)\b
+ scope: keyword.control.loop.tsql
+ - match: \b(?i:begin)\b
+ scope: keyword.control.flow.begin.tsql
+ - match: \b(?i:break)\b
+ scope: keyword.control.flow.break.tsql
+ - match: \b(?i:continue)\b
+ scope: keyword.control.flow.continue.tsql
+ - match: \b(?i:end)\b
+ scope: keyword.control.flow.end.tsql
+ - match: \b(?i:exec(?:ute)?)\b
+ scope: keyword.control.flow.execute.tsql
+ push: [expect-function-name, execute-args]
+ - match: \b(?i:go)\b
+ scope: keyword.control.flow.go.tsql
+ - match: \b(?i:goto)\b
+ scope: keyword.control.flow.goto.tsql
+ push: expect-label-name
+ - match: \b(?i:return)\b
+ scope: keyword.control.flow.return.tsql
+ - match: \b(?i:throw)\b
+ scope: keyword.control.flow.throw.tsql
+ - match: \b(?i:waitfor)\b
+ scope: keyword.control.flow.waitfor.tsql
+ push: waitfor-args
+ # builtin funtions
+ - match: \b(?i:print)\b
+ scope: support.function.tsql
+ - match: (?=\b(?i:raiserror)\b)
+ push: raiserror-args
+ # other keywords
+ - match: \b(?i:backup(?:\s+database)?)\b # https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-transact-sql?view=sql-server-ver15
+ scope: keyword.other.tsql
+ - match: \b(?i:to)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:disk|tape|url)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:pivot|unpivot)\b
+ scope: keyword.other.tsql
+ push: [maybe-table-alias, maybe-group]
+ - match: \b(?i:for)\b
+ scope: keyword.other.tsql
+ - match: \b\w+(?=::)
+ scope: storage.type.tsql
+ - match: \b(\w+)(:)
+ captures:
+ 1: entity.name.label.tsql
+ 2: punctuation.definition.label.tsql
+
+ execute-args:
+ - include: pop-on-top-level-reserved-word
+ - include: assignment-operators
+ - include: expressions
+ - include: else-pop
+
+ raiserror-args:
+ - match: \b(?i:with)\b
+ scope: keyword.other.tsql
+ set: raiserror-options
+ - include: pop-on-top-level-reserved-word
+ - include: expressions
+
+ raiserror-options:
+ - match: \b(?i:nowait|log|seterror)\b
+ scope: keyword.other.tsql
+ - include: else-pop
+
+ waitfor-args:
+ - match: \b(?i:delay|time)\b
+ scope: storage.type.tsql
+ pop: 1
+ - include: else-pop
+
+###[ CTE WITH STATEMENTS ]#####################################################
+
+ cte-with:
+ - match: \b(?i:with)\b(?=\s*(?:\[\w+\]|\w+)\s*\()
+ scope: keyword.other.dml.sql
+ push:
+ - cte-as
+ - maybe-column-name-list
+ - expect-cte-table-name
+ - match: \b(?i:with)\b #(?=\s*(?:\[\w+\]|\w+)\s*\bas\b)
+ scope: keyword.other.dml.sql
+ push:
+ - cte-as
+ - expect-cte-table-name
+
+ cte-as:
+ - match: \b(?i:as)\b
+ scope: keyword.operator.assignment.cte.tsql
+ - include: pop-on-top-level-reserved-word
+ - match: ','
+ scope: punctuation.separator.sequence.cte.tsql
+ push:
+ - maybe-column-name-list
+ - expect-cte-table-name
+ - include: expressions
+
+###[ EXPRESSIONS ]#############################################################
+
+ expressions:
+ - meta_prepend: true
+ - include: with-table-options
+ - include: like-expressions
+ - match: \b(?i:output)\b
+ scope: storage.modifier.output.tsql
+ - match: \b(?i:over|partition\s+by)\b
+ scope: keyword.other.sql
+ - match: \b(?i:unbounded|preceding|following|current\s+row|(?:rows|range)\s+between|next\s+value)\b
+ scope: keyword.other.sql
+ - match: \b(?i:cursor)\b
+ scope: support.type.tsql
+ push: inside-cursor-declaration
+ - match: \b(?i:when\s+(?:not\s+)?matched)\b
+ scope: keyword.control.conditional.case.sql
+ push: merge-condition
+ - match: \b(?i:include)\b
+ scope: keyword.other.sql
+ - match: \b(?i:within\s+group)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:at\s+time\s+zone)\b
+ scope: storage.modifier.tsql
+
+ built-in-scalar-function-calls:
+ - meta_append: true
+ - match: \b(?i:cast)\b
+ scope: support.function.tsql
+ push: cast-arguments
+ - match: \b((?i:convert))\s*(\()
+ scope: meta.function-call.sql
+ captures:
+ 1: support.function.scalar.sql
+ 2: meta.group.sql punctuation.section.arguments.begin.sql
+ push:
+ - inside-convert-arguments
+ - expect-type
+ - match: \b(?i:getdate)(?=\s*\()
+ scope: support.function.scalar.sql
+ push: function-call-arguments
+
+ cast-arguments:
+ - meta_scope: meta.function-call.sql
+ - match: \(
+ scope: meta.group.sql punctuation.section.arguments.begin.sql
+ set: inside-cast-arguments
+ - include: else-pop
+
+ inside-cast-arguments:
+ - meta_content_scope: meta.function-call.sql meta.group.sql
+ - match: \)
+ scope: meta.function-call.sql meta.group.sql punctuation.section.arguments.end.sql
+ pop: 1
+ - match: \b(?i:as)\b
+ scope: keyword.operator.assignment.tsql
+ push: expect-type
+ - include: expressions-or-column-names
+
+ inside-convert-arguments:
+ - meta_content_scope: meta.function-call.sql meta.group.sql
+ - match: \)
+ scope: meta.function-call.sql meta.group.sql punctuation.section.arguments.end.sql
+ pop: 1
+ - match: ','
+ scope: punctuation.separator.arguments.sql
+ - include: expressions-or-column-names
+
+ inside-function-call-arguments:
+ - meta_prepend: true
+ - include: datepart-units
+
+ user-defined-function-calls:
+ - meta_append: true
+ - match: (?={{identifier_for_lookahead}}\s*\()
+ push:
+ - function-call-arguments
+ - function-name
+ - single-identifier
+
+ function-name:
+ - meta_include_prototype: false
+ - meta_content_scope: variable.function.tsql
+ - include: immediately-pop
+
+ inside-cursor-declaration:
+ - meta_content_scope: meta.cursor-declaration.tsql
+ - match: |-
+ \b(?xi: DYNAMIC | FAST_FORWARD | FORWARD_ONLY | KEYSET | OPTIMISTIC
+ | READ_ONLY | SCROLL | SCROLL_LOCKS | STATIC | TYPE_WARNING )\b
+ scope: storage.modifier.tsql
+ - match: \b(?i:for)\b
+ scope: keyword.other.tsql
+ set: cursor-select-statement
+ - include: else-pop
+
+ cursor-select-statement:
+ - meta_content_scope: meta.cursor-declaration.tsql
+ - match: \b(?i:select)\b
+ scope: keyword.other.dml.sql
+ set: inside-cursor-select-statement
+ - include: else-pop
+
+ inside-cursor-select-statement:
+ - meta_content_scope: meta.cursor-declaration.tsql
+ - match: \b(?i:for)\b
+ scope: keyword.other.tsql
+ set: after-cursor-select-statement
+ - match: (?=\b(?i:open)\b)
+ pop: 1
+ - include: sql
+
+ after-cursor-select-statement:
+ - meta_scope: meta.cursor-declaration.tsql
+ - match: \b(?i:read\s+only|update(?:\s+of)?)\b
+ scope: storage.modifier.tsql
+ pop: 1
+ - include: else-pop
+
+ merge-condition:
+ - match: \b(?i:by\s+(?:source|target))\b
+ scope: keyword.other.tsql
+ - match: \b(?i:then)\b
+ scope: keyword.other.tsql
+ pop: 1
+ - include: values-or-expressions
+ - include: pop-on-top-level-reserved-word
+
+ values-or-expressions:
+ - include: dml-statements
+ - include: expressions
+
+###[ COLUMN EXPRESSIONS ]######################################################
+
+ maybe-column-declaration-list:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set:
+ - maybe-with-table-options
+ - maybe-filegroup
+ - inside-column-declaration-list
+ - include: else-pop
+
+ inside-column-declaration-list:
+ - meta_prepend: true
+ - match: \b(?i:rowguidcol|clustered|nonclustered)\b
+ scope: storage.modifier.tsql
+ - match: \b(?i:period\s+for\s+system_time)\b
+ scope: storage.modifier.tsql
+
+###[ FUNCTION EXPRESSIONS ]####################################################
+
+ expect-function-parameters:
+ - meta_prepend: true
+ - match: (@){{simple_identifier}}
+ scope: variable.parameter.tsql
+ captures:
+ 1: punctuation.definition.variable.tsql
+ push: expect-type
+ - include: comma-separators
+
+ expect-parameter-name:
+ - match: (@){{simple_identifier}}
+ captures:
+ 0: variable.parameter.sql
+ 1: punctuation.definition.variable.tsql
+ - match: \b(?i:as)\b
+ scope: keyword.context.tsql
+ - include: else-pop
+
+###[ WITH EXPRESSIONS ]########################################################
+
+ maybe-with-table-options:
+ - include: with-table-options
+ - include: else-pop
+
+ with-table-options:
+ - match: \b(?i:with)\b
+ scope: keyword.other.dml.sql
+ push: maybe-with-group
+
+ maybe-with-group:
+ - include: with-group
+ - include: else-pop
+
+ with-group:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-with-group
+
+ inside-with-group:
+ - meta_scope: meta.group.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ set: maybe-filegroup
+ - match: \b(?i:optimize\s+for\s+unknown)\b
+ scope: keyword.other.tsql
+ - match: \b((?i:optimize\s+for))\s*(\()
+ captures:
+ 1: keyword.other.tsql
+ 2: meta.group.tsql punctuation.section.group.begin.tsql
+ push: inside-optimize-for-group
+ - match: \b((?i:index|forceseek))\s*(\()
+ captures:
+ 1: keyword.other.tsql
+ 2: meta.group.tsql punctuation.section.group.begin.tsql
+ push: inside-index-names-group
+ - match: \b((?i:index))\s*(=)
+ captures:
+ 1: keyword.other.tsql
+ 2: keyword.operator.assignment.tsql
+ push: expect-index-name
+ - match: \b((?i:system_versioning))\s*(=)
+ captures:
+ 1: keyword.other.tsql
+ 2: keyword.operator.assignment.tsql
+ push: with-group-assignment
+ - match: \b((?i:history_table))\s*(=)
+ captures:
+ 1: keyword.other.tsql
+ 2: keyword.operator.assignment.tsql
+ push: expect-table-name
+ - include: with-simple-options
+
+ with-options:
+ - match: \b(?i:with)\b
+ scope: keyword.other.dml.sql
+ set: with-simple-options
+
+ with-simple-options:
+ - match: (?=;|\b(?i:GO|END)\b) # NOTE: we cant use the pop-on-top-level-reserved-word context here because it includes things like GRANT which are valid here
+ pop: true
+ - match: '{{simple_identifier}}'
+ scope: constant.language.with.tsql
+ - match: '='
+ scope: keyword.operator.assignment.tsql
+ push: with-other-assignment
+ - include: comma-separators
+
+ maybe-filegroup:
+ - match: \b(?i:on)\b(?!\s*{{identifier_for_lookahead}}\s*=)
+ scope: keyword.other.tsql
+ set: expect-filegroup-name
+ - include: else-pop
+
+ inside-index-names-group:
+ - meta_content_scope: meta.group.tsql
+ - match: \)
+ scope: meta.group.tsql punctuation.section.group.end.tsql
+ pop: 1
+ - include: comma-separators
+ - include: column-name-list
+ - include: literals-and-variables
+ - include: expect-index-names
+
+ inside-optimize-for-group:
+ - meta_content_scope: meta.group.tsql
+ - match: \)
+ scope: meta.group.tsql punctuation.section.group.end.tsql
+ pop: 1
+ - match: \b(?i:unknown)\b
+ scope: keyword.other.tsql
+ - include: expressions
+
+ with-group-assignment:
+ - include: with-group
+ - include: onoff-constants
+ - include: else-pop
+
+ with-other-assignment:
+ - match: (?=[,)])
+ pop: 1
+ - include: onoff-constants
+ - include: pop-on-top-level-reserved-word
+ - include: expressions
+ - match: (?=")
+ set:
+ - generic-identifier-name
+ - single-identifier
+ - match: \w+
+ scope: string.unquoted.tsql
+ - match: (?=\[)
+ set:
+ - generic-identifier-name
+ - single-identifier
+
+ generic-identifier-name:
+ - meta_include_prototype: false
+ - meta_content_scope: string.quoted.tsql
+ - include: immediately-pop
+
+###[ USER MANAGEMENT EXPRESSIONS ]#############################################
+
+ grant:
+ - meta_prepend: true
+ - match: \b(?i:on)\b
+ scope: keyword.context.resource.tsql
+ push: qualified-identifier
+ - include: with-options
+
+ user-privileges:
+ - meta_prepend: true
+ - match: \b(?i:control)\b
+ scope: constant.language.tsql
+ - match: \b(?i:from\s+external\s+provider)\b
+ scope: constant.language.tsql
+ - match: \b(?i:showplan)\b
+ scope: constant.language.sql
+ - match: \b(?i:view\s+server\s+state)\b
+ scope: constant.language.sql
+
+ qualified-identifier:
+ # https://learn.microsoft.com/en-us/sql/t-sql/statements/grant-transact-sql?view=sql-server-ver16#syntax
+ - match: \b(?i:(database|schema))(::)
+ captures:
+ 1: storage.type.tsql
+ 2: punctuation.accessor.double-colon.tsql
+ set:
+ - database-name
+ - single-identifier
+ - match: \b(?i:(login|role|user))(::)
+ captures:
+ 1: storage.type.tsql
+ 2: punctuation.accessor.double-colon.tsql
+ set:
+ - user-name
+ - single-identifier
+ - match: \b(?i:(\w+))(::)
+ captures:
+ 1: storage.type.tsql
+ 2: punctuation.accessor.double-colon.tsql
+ set:
+ - other-name
+ - single-identifier
+ - match: (?=\S)
+ set:
+ - maybe-double-colon-accessor
+ - generic-identifier-name
+ - single-identifier
+
+ maybe-double-colon-accessor:
+ - match: '::'
+ scope: punctuation.accessor.double-colon.tsql
+ set: qualified-identifier
+ - match: (?=\S)
+ pop: true
+
+###[ TABLE NAMES OR SUBQUERIES ]###############################################
+
+ table-subquery:
+ - meta_append: true
+ - match: \b(?i:openxml)\b
+ scope: meta.table-valued-function-name.sql support.function.tsql
+ set:
+ - maybe-with-column-definition
+ - function-call-arguments
+ - match: \b(?i:(openrowset))\s*(\()
+ scope: meta.function-call.tsql
+ captures:
+ 1: meta.table-valued-function-name.sql support.function.tsql
+ 2: punctuation.section.arguments.begin.tsql
+ set: inside-openrowset-call
+
+ inside-openrowset-call:
+ - meta_content_scope: meta.group.sql
+ - match: \)
+ scope: meta.function-call.tsql meta.group.tsql punctuation.section.arguments.end.sql
+ set: maybe-table-alias
+ - match: ';'
+ scope: punctuation.separator.sequence.tsql
+ - include: inside-function-call-arguments
+
+ table-name-fail-if-function-call:
+ - meta_prepend: true
+ - include: table-hints-without-with
+
+ maybe-table-alias:
+ - meta_prepend: true
+ - include: table-timespecs
+ - include: with-table-options
+ - match: (?=\b(?i:unpivot|pivot)\b)
+ pop: 1
+
+ table-alias-name:
+ - meta_prepend: true
+ - match: ''
+ set: maybe-table-sample
+
+ maybe-table-sample:
+ - include: table-hints-without-with
+ - include: with-table-options
+ - match: \b(?i:tablesample(?:\s+system)?)\b
+ scope: keyword.other.sql
+ push:
+ - after-tablesample-group
+ - maybe-table-sample-group
+ - include: else-pop
+
+ maybe-table-sample-group:
+ - match: \(
+ scope: punctuation.section.group.begin.sql
+ set: inside-tablesample-group
+ - include: else-pop
+
+ inside-tablesample-group:
+ - meta_scope: meta.group.tablesample.sql
+ - match: \)
+ scope: punctuation.section.group.end.sql
+ pop: 1
+ - match: \b(?i:rows|percent)\b
+ scope: constant.language.sql
+ - include: expressions
+
+ after-tablesample-group:
+ - match: \b(?i:repeatable)\b
+ scope: constant.language.sql
+ pop: 1
+ - include: else-pop
+
+ table-hints-without-with:
+ # https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver15#arguments
+ - match: |-
+ (?xi)
+ (\() \s*
+ ( nolock | readuncommitted | updlock | repeatableread | serializable
+ | readcommitted | tablock | tablockx | paglock | rowlock | nowait
+ | readpast | xlock | snapshot | noexpand )
+ \s* (\))
+ scope: meta.group.tsql invalid.deprecated.table-hint-without-with.tsql
+ captures:
+ 1: punctuation.section.group.begin.tsql
+ 2: constant.language.table-hint.tsql
+ 3: punctuation.section.group.end.tsql
+
+ maybe-with-column-definition:
+ - match: \b(?i:with)\b
+ scope: keyword.other.tsql
+ set: maybe-column-declaration-list
+ - include: else-pop
+
+ table-timespec-args:
+ - meta_prepend: true
+ - match: \b(?i:contained\s+in)
+ scope: keyword.operator.logical.tsql
+ set: maybe-group
+
+###[ TYPES ]###################################################################
+
+ expect-type:
+ - meta_prepend: true
+ - match: \b(?i:as)\b
+ scope: keyword.other.tsql
+ set: computed-column-definition
+
+ computed-column-definition:
+ - meta_content_scope: meta.computed-column-definition.tsql
+ - match: (?=[,)])
+ pop: 1
+ - match: (?=\b(?i:constraint)\b)
+ pop: 1
+ - include: expressions-or-column-names
+
+ built-in-type:
+ - meta_prepend: true
+ - match: |-
+ (?xi)
+ {{enclosed_type_begin}}
+ {{simple_types}}
+ {{enclosed_type_end}}
+ scope: storage.type.sql
+ pop: 1
+ - match: |-
+ (?xi)
+ {{enclosed_type_begin}}
+ {{types_with_optional_number}}
+ {{enclosed_type_end}}
+ scope: storage.type.sql
+ set: optional-number-after-type
+ - match: |-
+ (?xi)
+ (?:{{enclosed_type_begin}}|\b)
+ table
+ (?:{{enclosed_type_end}}|\b)
+ scope: storage.type.sql
+ set:
+ - create-table-args
+ - maybe-column-declaration-list
+ - match: |-
+ (?xi)
+ {{types_with_optional_number}}
+ scope: storage.type.sql
+ set: optional-number-after-type
+
+ optional-number-after-type:
+ - match: |-
+ (?x)
+ \s*
+ (\()\s*
+ (?i:(\d+)|(max))
+ \s*(?:(,)\s*(\d+))?
+ (\))
+ scope: storage.type.sql
+ captures:
+ 1: punctuation.section.group.begin.tsql
+ 2: constant.numeric.sql
+ 3: constant.language.max.sql
+ 4: punctuation.separator.sequence.sql
+ 5: constant.numeric.sql
+ 6: punctuation.section.group.end.tsql
+ pop: 1
+ - include: else-pop
+
+ inside-user-type:
+ - meta_prepend: true
+ - include: variables
+
+ after-type:
+ - meta_prepend: true
+ - match: \b(?i:generated\s+always\s+as\s+row\s+(?:start|end)(?:\s+hidden)?)\b
+ scope: keyword.other.tsql
+ - match: \b(?i:encrypted\s+with)\b
+ scope: storage.modifier.tsql
+ set:
+ - maybe-table-alias
+ - maybe-with-group
+ - match: \b(?i:readonly)\b
+ scope: storage.modifier.tsql
+ - include: collate-expressions
+
+###[ IDENTIFIERS ]#############################################################
+
+ expect-cte-table-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [cte-table-name, single-identifier]
+
+ cte-table-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.cte-table-name.sql
+ - include: immediately-pop
+
+ expect-cursor-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [cursor-name, single-identifier]
+
+ cursor-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.cursor-name.sql
+ - include: immediately-pop
+
+ expect-filegroup-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [filegroup-name, single-identifier]
+
+ filegroup-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.filegroup-name.tsql
+ - include: immediately-pop
+
+ expect-label-name:
+ # prevent prototypes from inheriting syntaxes
+ - meta_include_prototype: false
+ - include: comments
+ - match: (?=\S)
+ set: [label-name, single-identifier]
+
+ label-name:
+ - meta_include_prototype: false
+ - meta_content_scope: meta.label-name.sql
+ - include: immediately-pop
+
+ maybe-identifier-accessor:
+ - meta_prepend: true
+ - match: \s*(\.{2,})\s*
+ captures:
+ 1: punctuation.accessor.dot.sql
+ set: single-identifier
+
+ identifier-part:
+ - meta_prepend: true
+ - match: \b(?i:inserted|deleted)(\.)
+ scope: constant.language.table.tsql
+ captures:
+ 1: punctuation.accessor.dot.tsql
+ - include: square-bracketed-identifier-part
+
+ square-bracketed-identifier-part:
+ - match: \[
+ scope: punctuation.definition.identifier.begin.sql
+ set: inside-square-bracketed-identifier-part
+
+ inside-square-bracketed-identifier-part:
+ # note: may contain foreign variable interpolation
+ - match: \]
+ scope: punctuation.definition.identifier.end.sql
+ pop: 1
+
+ inside-simple-identifier-part:
+ - meta_prepend: true
+ - include: variables
+ - match: \#
+ scope: punctuation.definition.variable.tsql
+
+###[ LITERALS ]################################################################
+
+ literals-and-variables:
+ - meta_prepend: true
+ - include: variables
+
+ onoff-constants:
+ - match: \b(?i:on|off)\b
+ scope: constant.language.boolean.tsql
+
+ numbers:
+ - meta_prepend: true
+ - match: (0x)(\h+)
+ scope: meta.number.integer.hexadecimal.tsql
+ captures:
+ 1: constant.numeric.base.tsql
+ 2: constant.numeric.value.tsql
+
+ strings:
+ - meta_append: true
+ - match: N'
+ scope: punctuation.definition.string.begin.sql
+ push: inside-single-quoted-string
+
+ variables:
+ - match: (@){{simple_identifier}}
+ scope: variable.other.readwrite.sql
+ captures:
+ 1: punctuation.definition.variable.sql
+ push: maybe-variable-scoped-function-call
+ - match: |-
+ (?xi)(@@)
+ (?: cursor_rows | connections | cpu_busy | datefirst | dbts | error
+ | fetch_status | identity | idle | io_busy | langid | language
+ | lock_timeout | max_connections | max_precision | nestlevel | options
+ | packet_errors | pack_received | pack_sent | procid | remserver
+ | rowcount | servername | servicename | spid | textsize | timeticks
+ | total_errors | total_read | total_write | trancount | version )\b
+ scope: support.variable.global.sql
+ captures:
+ 1: punctuation.definition.variable.sql
+ - match: '\$action\b' # has to be lowercase
+ scope: variable.language.tsql
+ - match: \b(?i:default)\b
+ scope: variable.language.tsql
+
+ maybe-variable-scoped-function-call:
+ - match: \s*\.(?=\s*\w+\s*\()
+ scope: punctuation.accessor.dot.tsql
+ - include: immediately-pop
+
+ datepart-units:
+ # https://learn.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-ver16
+ - match: \b(?i:DAY|MONTH|YEAR|QUARTER|DAYOFYEAR|WEEK|HOUR|MINUTE|SECOND|MILLISECOND|MICROSECOND|NANOSECOND)\b(?!\s*\.)
+ scope: constant.language.tsql
+ - match: \b(?i:D?D|YYYY|YY?|Q?Q|M?M|DY|WK|WW|HH|MI|N|SS?|MS|MCS|NS)\b(?!\s*\.)
+ scope: constant.language.tsql
+
+###[ LIKE EXPRESSIONS ]########################################################
+ inside-like-single-quoted-string:
+ - meta_append: true
+ - match: |-
+ (?x)
+ (\[)(\^)?
+ (?:.|[^]'-]+?)
+ (?:(-)[^]'-]*)?
+ (\])
+ scope: meta.set.like.sql
+ captures:
+ 1: keyword.control.set.begin.sql
+ 2: keyword.control.set.negation.sql
+ 3: constant.other.range.sql
+ 4: keyword.control.set.end.sql
+
+###[ OPERATORS ]###############################################################
+
+ operators:
+ - meta_append: true
+ - match: '%'
+ scope: keyword.operator.arithmetic.tsql
+ - match: '::'
+ scope: punctuation.accessor.double-colon.tsql
+
+ augmented-assignment-operators:
+ - match: '[-+/*%^|]='
+ scope: keyword.operator.assignment.tsql
diff --git a/SQL/syntax_test_sql.sql b/SQL/syntax_test_sql.sql
deleted file mode 100644
index 59ee2e7771..0000000000
--- a/SQL/syntax_test_sql.sql
+++ /dev/null
@@ -1,312 +0,0 @@
--- SYNTAX TEST "Packages/SQL/SQL.sublime-syntax"
-
-SELECT 'Foo Bar';
--- ^^^^^^^^^ string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ punctuation.definition.string.end
--- ^ punctuation.terminator.statement - string
-
-SELECT 'Foo '' Bar';
--- ^^ constant.character.escape.sql
-
-SELECT "My "" Crazy Column Name" FROM my_table;
--- ^^ constant.character.escape.sql
-
-SELECT "My -- Crazy Column Name" FROM my_table;
--- ^^ - comment - punctuation
-
-SELECT "My /* Crazy Column Name" FROM my_table;
--- ^^ - comment - punctuation
-
-
-;CREATE TABLE foo (id INTEGER PRIMARY KEY);
- -- <- keyword.other.create
---^^^^^ keyword.other.create
--- ^^^^^ keyword.other
--- ^^^ entity.name.function
--- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - entity.name.function
-
-create table some_schema.test2( id serial );
---^^^^ meta.create keyword.other.create
--- ^^^^^ meta.create keyword.other
--- ^^^^^^^^^^^^ - entity.name.function
--- ^ punctuation.accessor.dot
--- ^^^^^ entity.name.function
--- ^^^^^^^^^^^^^^ - entity.name.function
-
-create table some_schema . test2 ( id serial );
---^^^^ meta.create keyword.other.create
--- ^^^^^ meta.create keyword.other
--- ^^^^^^^^^^^^^^ - entity.name
--- ^ punctuation.accessor.dot
--- ^^^^^ entity.name.function
--- ^^^^^^^^^^^^^^^ - entity.name.function
-
-create table "testing123" (id integer);
---^^^^ meta.create keyword.other.create
--- ^^^^^ meta.create keyword.other
--- ^ - entity.name.function
--- ^^^^^^^^^^ entity.name.function
--- ^^^^^^^^^^^^^^^^ - entity.name.function
-
-create table `dbo`."testing123" (id integer);
---^^^^ meta.create keyword.other.create
--- ^^^^^ meta.create keyword.other
--- ^^^^^^^ - entity.name.function
--- ^ punctuation.accessor.dot
--- ^^^^^^^^^^ entity.name.function
--- ^^^^^^^^^^^^^^^^ - entity.name.function
-
-create table IF NOT EXISTS `testing123` (
--- ^^^^^^^^^^^^^^^^^^^^^^^^ - meta.toc-list
--- ^^ keyword.control.flow
--- ^^^ keyword.operator.logical
--- ^^^^^^ keyword.operator.logical
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `lastchanged` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
--- ^^^^^^^^^ storage.type.sql
--- ^^^^^^^^^^^^^^^^^ support.function.scalar.sql
--- ^^^^^^^^^ storage.modifier.sql
- `col` bool DEFAULT FALSE,
--- ^^^^ storage.type.sql
--- ^^^^^^^ storage.modifier.sql
--- ^^^^^ constant.language.boolean.false.sql
--- ^ punctuation.separator.sequence
- `fkey` INT UNSIGNED NULL REFERENCES test2(id),
--- ^^^^^^^^^^ storage.modifier.sql
- `version` tinytext DEFAULT NULL COMMENT 'important clarification',
--- ^^^^^^^^ storage.type.sql
- `percentage` float DEFAULT '0',
- UNIQUE KEY `testing123_search` (`col`, `version`),
--- ^^^^^^^^^^ storage.modifier.sql
- KEY `testing123_col` (`col`),
--- ^^^ storage.modifier.sql
- FULLTEXT KEY `testing123_version` (`version`)
-) ENGINE=MyISAM AUTO_INCREMENT=42 DEFAULT CHARSET=utf8;
-
-create table fancy_table (
- id SERIAL,
--- ^^^^^^ storage.type.sql
- foreign_id integer,
--- ^^^^^^^ storage.type.sql
- myflag boolean DEFAULT false,
--- ^^^^^^^ storage.type.sql
- mycount double precision DEFAULT 1,
--- ^^^^^^^^^^^^^^^^^ storage.type.sql
- fancy_column character varying(42) DEFAULT 'nice'::character varying,
--- ^^^^^^^^^^^^^^^^^^ storage.type.sql
- mytime timestamp(3) without time zone DEFAULT now(),
--- ^^^^^^^^^^^^^^^^^ storage.type.sql
- mytime2 timestamp(3) without time zone DEFAULT '2008-01-18 00:00:00'::timestamp(3) without time zone,
--- ^^^^^^^^^^^^^^^^^^^ storage.type.sql
- primary key (id),
--- ^^^^^^^^^^^ storage.modifier.sql
- UNIQUE (foreign_id),
- CONSTRAINT fancy_table_valid1 CHECK (id <> foreign_id)
--- ^^^^^^^^^^ storage.modifier.sql
--- ^^^^^ storage.modifier.sql
-);
-
-CREATE INDEX ON fancy_table(mytime);
--- ^^^^^ keyword.other.sql
--- ^^ - entity.name.function.sql
--- ^^^^^^^^^^^ entity.name.function.sql
-
-CREATE INDEX ON fancy_table USING gin (fancy_column gin_trgm_ops);
--- ^^^^^ keyword.other.sql
--- ^^ - entity.name.function.sql
-
-CREATE UNIQUE INDEX ON fancy_table(fancy_column,mycount) WHERE myflag IS NULL;
--- ^^^^^^^^^^^^ keyword.other.sql
--- ^^ - entity.name.function.sql
--- ^^^^^^^^^^^ entity.name.function.sql
--- ^^^^^ keyword.other.DML.sql
--- ^^ keyword.operator.logical.sql
--- ^^^^ constant.language.null.sql
-
-create fulltext index if not exists `myindex` ON mytable;
--- ^^^^^^^^^^^^^^ keyword.other.sql
-
-ALTER TABLE dbo.testing123 ADD COLUMN mycolumn longtext;
--- ^^^ keyword.other.add.sql
--- ^^^^^^ keyword.other.sql
--- ^^^^^^^^ storage.type.sql
-
-ALTER TABLE testing123 CHANGE COLUMN mycolumn mycolumn ENUM('foo', 'bar');
--- ^^^^ storage.type.sql
-
-DROP TABLE IF EXISTS testing123;
--- <- meta.drop.sql keyword.other.create.sql
--- ^^^^^^ keyword.operator.logical.sql
-
-select *
-from some_table
-where exists(select * from other_table where id = some_table.id)
--- ^^^^^^ keyword.operator.logical
-
-SELECT
-(
-SELECT CASE field
-USING a
--- <- keyword.other.DML
- WHEN 1
- THEN -- comment's say that
--- ^ comment.line.double-dash
- EXISTS(
- select 1)
- ELSE NULL
- END
-) as result
-
-
-/*
--- <- comment.block punctuation.definition.comment.begin
-This is a
-multiline comment
--- ^^^^^^^^^^^^^^^ source.sql comment.block.sql
-*/
--- <- comment.block punctuation.definition.comment.end
-
-/**
- *
--- ^ punctuation.definition.comment.sql
-*/
-
-select
-
-
- <=>
--- ^^^ keyword.operator.comparison.sql
-
-SELECT *,
--- ^^^ keyword.other.DML.sql
--- ^ constant.other.wildcard.asterisk.sql
- f.id AS database_id
--- ^^ keyword.operator.assignment.alias.sql
-FROM foo
-WHERE f.a IS NULL
--- ^^ keyword.other.DML.sql
--- ^^ keyword.operator.logical.sql
--- ^^^^ constant.language.null.sql
- AND f.b IS NOT NULL
--- ^^^ keyword.operator.logical.sql
--- ^^ keyword.operator.logical.sql
--- ^^^ keyword.operator.logical.sql
--- ^^^^ constant.language.null.sql
-
-
-SELECT columns FROM table WHERE
- column LIKE '%[[]SQL Server Driver]%'
--- ^^^^ keyword.operator.logical
--- ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.like string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ keyword.operator.wildcard
--- ^^^ meta.set.like
--- ^ keyword.control.set.begin
--- ^ keyword.control.set.end
--- ^^^^^^^^^^^^^^^^^^ - constant - keyword
--- ^ keyword.operator.wildcard
--- ^ punctuation.definition.string.end
--- ^^ - meta.string - string
-
-SELECT columns FROM table WHERE
- column LIKE '%[SQL Server Driver]%'
--- ^^^^ keyword.operator.logical
--- ^^^^^^^^^^^^^^^^^^^^^^^ meta.string.like string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ keyword.operator.wildcard
--- ^^^^^^^^^^^^^^^^^^^ meta.set.like
--- ^ keyword.control.set.begin
--- ^ keyword.control.set.end
--- ^^^^^^^^^^^^^^^ - constant - keyword
--- ^ keyword.operator.wildcard
--- ^ punctuation.definition.string.end
--- ^^ - meta.string - string
-
-SELECT columns FROM table WHERE
- column LIKE '%[^a-f]%'
--- ^^^^ keyword.operator.logical
--- ^^^^^^^^^^ meta.string.like string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ keyword.operator.wildcard
--- ^^^^^^ meta.set.like
--- ^ keyword.control.set.begin
--- ^ keyword.control.set.negation
--- ^ constant.other.range
--- ^ keyword.control.set.end
--- ^ keyword.operator.wildcard
--- ^ punctuation.definition.string.end
--- ^^ - meta.string - string
-
-SELECT columns FROM table WHERE
- column LIKE 'hello_world'
--- ^^^^ keyword.operator.logical
--- ^^^^^^^^^^^^ meta.string.like string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ keyword.operator.wildcard
--- ^ punctuation.definition.string.end
--- ^^ - meta.string - string
-
-SELECT columns FROM table WHERE
- column LIKE '%\[SQL Server Driver]^%\__' ESCAPE '\'
--- ^^^^ keyword.operator.logical
--- ^ keyword.operator.wildcard
--- ^^ constant.character.escape
--- ^ - constant
--- ^ keyword.operator.wildcard
--- ^^ constant.character.escape
--- ^ keyword.operator.wildcard
--- ^^^^^^ keyword.operator.word
--- ^^^ string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ constant.character.escape
--- ^ punctuation.definition.string.end
-
-SELECT columns FROM table WHERE
- column LIKE '%\[SQL Server Driver]^%\__'
--- ^^^^ keyword.operator.logical
--- ^ keyword.operator.wildcard
--- ^^ constant.character.escape
--- ^ - constant
--- ^ keyword.operator.wildcard
--- ^^ constant.character.escape
--- ^ keyword.operator.wildcard
- ESCAPE '\'
--- ^^^^^^ keyword.operator.word
--- ^^^ string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ constant.character.escape
--- ^ punctuation.definition.string.end
-
-SELECT columns FROM table WHERE
- column LIKE '%\^[SQL Server Driver]^%_^_' ESCAPE '^'
--- ^^^^ keyword.operator.logical
--- ^ keyword.operator.wildcard
--- ^ - constant
--- ^^ constant.character.escape
--- ^^ constant.character.escape
--- ^ keyword.operator.wildcard
--- ^^ constant.character.escape
--- ^^^^^^ keyword.operator.word
--- ^^^ string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ constant.character.escape
--- ^ punctuation.definition.string.end
-
-SELECT columns FROM table WHERE
- column LIKE '%\^[SQL Server Driver]^%_^_\_{{--' ESCAPE '{' -- uncatered for escape char, scope operators as though unescaped
--- ^^^^ keyword.operator.logical
--- ^ keyword.operator.wildcard
--- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - constant
--- ^^^^^^^^^^^^^^^^^^^ meta.set.like
--- ^^^^^^^^^^^ - meta.set
--- ^^ keyword.operator.wildcard
--- ^ keyword.operator.wildcard
--- ^ keyword.operator.wildcard
--- ^^^^^^^^^^^^^^^ - comment
--- ^^^^^^ keyword.operator.word
--- ^^^ string.quoted.single
--- ^ punctuation.definition.string.begin
--- ^ constant.character.escape
--- ^ punctuation.definition.string.end
--- ^^ comment.line.double-dash punctuation.definition.comment
diff --git a/SQL/tests/indentation/syntax_test_indentation_tsql.sql b/SQL/tests/indentation/syntax_test_indentation_tsql.sql
new file mode 100644
index 0000000000..1816cead2a
--- /dev/null
+++ b/SQL/tests/indentation/syntax_test_indentation_tsql.sql
@@ -0,0 +1,58 @@
+-- SYNTAX TEST reindent "Packages/SQL/TSQL.sublime-syntax"
+SELECT *
+FROM (
+ SELECT *
+ FROM a
+ INNER JOIN b ON a.ID = b.ID
+) alias
+WHERE 1 = 1
+GO
+
+BEGIN
+ INSERT INTO a
+ VALUES (123, 456)
+END
+
+BEGIN
+ INSERT INTO a
+ VALUES (123, 456)
+GO
+ INSERT INTO b
+ VALUES (123, 456)
+END
+
+SELECT
+a,
+b,
+c
+FROM foo
+
+SELECT a
+,b
+,c
+FROM foo
+
+CREATE TABLE hello (
+ field1 int,
+ field2 nvarchar(50)
+)
+
+CREATE UNIQUE NONCLUSTERED INDEX IX_some_index ON dbo.some_table(
+ some_column ASC
+)
+
+SET @fileDate = CONVERT(VARCHAR(20),GETDATE(),112)
+
+BEGIN RAISERROR ('File "%s" does not exist', 16, -1, @FromFile)
+END
+
+SELECT COALESCE(a.field1, b.field2, c.field1) AS Blah, ISNULL(d.field1, 'default') as field1
+
+'no indentation increase when an unclosed open paren is in a string('
+BEGIN
+ 'no indentation decrease when a close paren with no matching open paren on the same line is in a string)'
+ null
+ -- no indentation increase when an unclosed open paren is in a comment (
+ --no indentation decrease when a close paren with no matching open paren on the same line is in a comment )
+ null
+END
diff --git a/SQL/tests/symbols/syntax_test_symbols_tsql.sql b/SQL/tests/symbols/syntax_test_symbols_tsql.sql
new file mode 100644
index 0000000000..ad0ec2e548
--- /dev/null
+++ b/SQL/tests/symbols/syntax_test_symbols_tsql.sql
@@ -0,0 +1,24 @@
+-- SYNTAX TEST "Packages/SQL/TSQL.sublime-syntax"
+
+CREATE TABLE hello (
+ -- @@@@@ definition
+ field1 int,
+ field2 nvarchar(50)
+)
+
+CREATE UNIQUE NONCLUSTERED INDEX IX_some_index ON dbo.some_table(
+ -- @@@@@@@@@@@@@ definition
+ some_column ASC
+)
+
+SET @fileDate = CONVERT(VARCHAR(20),GETDATE(),112)
+-- @@@@@@@ reference
+-- @@@@@@@ reference
+
+BEGIN RAISERROR ('File "%s" does not exist', 16, -1, @FromFile)
+ -- @@@@@@@@@ reference
+END
+
+SELECT COALESCE(a.field1, b.field2, c.field1) AS Blah, ISNULL(d.field1, 'default') as field1
+-- @@@@@@@@ reference
+-- @@@@@@ reference
diff --git a/SQL/tests/syntax/syntax_test_cassandra.cql b/SQL/tests/syntax/syntax_test_cassandra.cql
new file mode 100644
index 0000000000..1944904a9b
--- /dev/null
+++ b/SQL/tests/syntax/syntax_test_cassandra.cql
@@ -0,0 +1,582 @@
+-- SYNTAX TEST "Packages/SQL/Cassandra.sublime-syntax"
+
+CREATE KEYSPACE killrvideo WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
+--^^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.create
+--^^^^ keyword.other.ddl
+-- ^^^^^^^^ keyword.other
+-- ^^^^^^^^^^ entity.name.struct.other
+-- ^^^^ keyword.other
+-- ^ keyword.operator
+-- ^ punctuation.section.braces.begin
+-- ^^^^^^^ string.quoted.single
+-- ^ punctuation.separator.key-value
+-- ^^^^^^^^^^^^^^^^ string.quoted.single
+-- ^ punctuation.separator.sequence
+-- ^^^^^^^^^^^^^^^^^^^^ string.quoted.single
+-- ^ punctuation.separator.key-value
+-- ^ meta.number.integer.decimal constant.numeric.value
+-- ^ punctuation.section.braces.end
+-- ^ punctuation.terminator.statement
+
+select someid, token(someid), something
+--^^^^ keyword.other.dml
+-- ^^^^^^ meta.column-name
+-- ^ punctuation.separator.sequence
+-- ^^^^^ meta.function-call support.function
+-- ^ meta.function-call meta.group punctuation.section.arguments.begin
+-- ^^^^^^ meta.function-call meta.group meta.column-name
+-- ^ meta.function-call meta.group punctuation.section.arguments.end
+-- ^ punctuation.separator.sequence
+-- ^^^^^^^^^ meta.column-name
+from something_by_someid
+--^^ keyword.other.dml
+-- ^^^^^^^^^^^^^^^^^^^ meta.table-name
+where token(someid) >= token(d821d7d8-8265-402e-9a72-c61ab8473ab6)
+--^^^ keyword.other.dml
+-- ^^^^^^^^^^^^^ meta.function-call
+-- ^^^^^ support.function
+-- ^^^^^^^^ meta.group
+-- ^ punctuation.section.arguments.begin
+-- ^^^^^^ meta.column-name
+-- ^ punctuation.section.arguments.end
+-- ^^ keyword.operator.comparison
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call
+-- ^^^^^ support.function
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group
+-- ^ punctuation.section.arguments.begin
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.uuid
+-- ^ punctuation.section.arguments.end
+-- ^ - meta
+and token(someid) <= token(cf0acefc-ccff-42a0-8753-65d82e9c9b0f)
+limit 2000;
+-- <- keyword.other.dml
+--^^^ keyword.other.dml
+-- ^^^^ meta.number.integer.decimal constant.numeric.value
+-- ^ punctuation.terminator.statement
+
+select count(someid)
+from something_by_someid
+where something = 'abc'
+-- ^^ keyword.other.dml
+-- ^^^^^^^^^ meta.column-name
+-- ^ keyword.operator.comparison
+-- ^^^^^ string.quoted.single
+limit 2000
+allow filtering;
+-- ^^^^^^^^^^^^ keyword.other.dml
+-- ^ punctuation.terminator.statement
+
+insert into something_by_countrycode (someid, countrycode) values (:someid, :countrycode);
+-- ^^^^^^^^ keyword.other.dml
+-- ^^^^^^^^^^^^^^^^^^^^^^^^ meta.table-name
+-- ^^^^^^^^^^^^^^^^^^^^^ meta.group
+-- ^ punctuation.section.group.begin
+-- ^^^^^^ meta.column-name
+-- ^ punctuation.separator.sequence
+-- ^^^^^^^^^^^ meta.column-name
+-- ^ punctuation.section.group.end
+-- ^^^^^^ keyword.other.dml.II
+-- ^^^^^^^^^^^^^^^^^^^^^^^ meta.group
+-- ^ punctuation.section.group.begin
+-- ^^^^^^^ variable.other.constant
+-- ^ punctuation.separator.sequence
+-- ^ punctuation.definition.variable
+-- ^^^^^^^^^^^ variable.other.constant
+-- ^ punctuation.terminator.statement
+
+CREATE TABLE IF NOT EXISTS userpermissions_by_userid (
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.create
+-- ^^^ keyword.other.ddl
+-- ^^^^^ keyword.other.ddl
+-- ^^ keyword.control.conditional.if
+-- ^^^ keyword.operator.logical
+-- ^^^^^^ keyword.operator.logical
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.struct
+-- ^ meta.group.table-columns punctuation.section.group.begin
+ userid uuid,
+-- ^^^^^^^^^^^^^ meta.statement.create meta.group.table-columns
+-- ^^^^^^ meta.column-name
+-- ^^^^ storage.type
+-- ^ punctuation.separator.sequence
+ permissions frozen>,
+-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.create meta.group.table-columns
+-- ^^^^^^^^^^^ meta.column-name
+-- ^^^^^^ - meta.generic
+-- ^^^^ meta.generic.cql - meta.generic meta.generic
+-- ^^^^^^ meta.generic.cql meta.generic.cql - meta.generic meta.generic meta.generic
+-- ^ meta.generic.cql - meta.generic meta.generic
+-- ^ - meta.generic
+-- ^^^^^^ storage.type
+-- ^ punctuation.definition.generic.begin
+-- ^^^ storage.type
+-- ^ punctuation.definition.generic.begin
+-- ^^^^ storage.type
+-- ^^ punctuation.definition.generic.end
+-- ^ punctuation.separator.sequence
+ storage tuple