Repository: AlecStrong/sql-psi
Pull request #342 (2022-03-23 16:44:03)

Support NULLS FIRST/LAST in sqlite


Patch:
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/DialectPreset.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/DialectPreset.kt
index 7b9f08e..39eeabc 100644
--- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/DialectPreset.kt
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/DialectPreset.kt
@@ -11,6 +11,7 @@ import com.alecstrong.sql.psi.core.sqlite_3_18.SqliteParserUtil as Sqlite_3_18Ut
 import com.alecstrong.sql.psi.core.sqlite_3_18.psi.mixins.ColumnDefMixin as Sqlite_3_18ColumnDefMixin
 import com.alecstrong.sql.psi.core.sqlite_3_24.SqliteParserUtil as Sqlite_3_24Util
 import com.alecstrong.sql.psi.core.sqlite_3_25.SqliteParserUtil as Sqlite_3_25Util
+import com.alecstrong.sql.psi.core.sqlite_3_30.SqliteParserUtil as Sqlite_3_30Util
 import com.alecstrong.sql.psi.core.sqlite_3_35.SqliteParserUtil as Sqlite_3_35Util
 
 enum class DialectPreset {
@@ -44,9 +45,16 @@ enum class DialectPreset {
       Sqlite_3_25Util.overrideSqlParser()
     }
   },
-  SQLITE_3_35 {
+  SQLITE_3_30 {
     override fun setup() {
       SQLITE_3_25.setup()
+      Sqlite_3_30Util.reset()
+      Sqlite_3_30Util.overrideSqlParser()
+    }
+  },
+  SQLITE_3_35 {
+    override fun setup() {
+      SQLITE_3_30.setup()
       Sqlite_3_35Util.reset()
       Sqlite_3_35Util.overrideSqlParser()
     }
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/sqlite_3_30/sqlite.bnf b/core/src/main/kotlin/com/alecstrong/sql/psi/core/sqlite_3_30/sqlite.bnf
new file mode 100644
index 0000000..60572c5
--- /dev/null
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/sqlite_3_30/sqlite.bnf
@@ -0,0 +1,23 @@
+{
+  // Specify the parent parser.
+  overrides="com.alecstrong.sql.psi.core.SqlParser"
+  elementTypeClass = "com.alecstrong.sql.psi.core.SqlElementType"
+
+  implements="com.alecstrong.sql.psi.core.psi.SqlCompositeElement"
+  extends="com.alecstrong.sql.psi.core.psi.SqlCompositeElementImpl"
+  psiClassPrefix = "Sqlite"
+
+  parserImports=[
+    "static com.alecstrong.sql.psi.core.psi.SqlTypes.COLLATE"
+    "static com.alecstrong.sql.psi.core.psi.SqlTypes.ASC"
+    "static com.alecstrong.sql.psi.core.psi.SqlTypes.DESC"
+  ]
+}
+
+overrides ::= ordering_term
+
+ordering_term ::= <<expr '-1'>> [ COLLATE {collation_name} ] [ ASC | DESC ] [ 'NULLS' ( 'FIRST' | 'LAST' ) ] {
+  extends = "com.alecstrong.sql.psi.core.psi.impl.SqlOrderingTermImpl"
+  implements = "com.alecstrong.sql.psi.core.psi.SqlOrderingTerm"
+  override = true
+}


Test patch:
diff --git a/core/src/test/fixtures_sqlite_3_30/nulls/1.s b/core/src/test/fixtures_sqlite_3_30/nulls/1.s
new file mode 100644
index 0000000..6a654cf
--- /dev/null
+++ b/core/src/test/fixtures_sqlite_3_30/nulls/1.s
@@ -0,0 +1,14 @@
+CREATE TABLE test(
+  id TEXT
+);
+
+SELECT * FROM test ORDER BY id NULLS LAST;
+SELECT * FROM test ORDER BY id NULLS FIRST;
+
+UPDATE test SET id = 'id' ORDER BY id NULLS LAST LIMIT 1;
+UPDATE test SET id = 'id' ORDER BY id NULLS FIRST LIMIT 1;
+
+DELETE FROM test ORDER BY id NULLS LAST LIMIT 1;
+DELETE FROM test ORDER BY id NULLS FIRST LIMIT 1;
+
+
diff --git a/core/src/test/kotlin/com/alecstrong/sql/psi/core/FixturesTest.kt b/core/src/test/kotlin/com/alecstrong/sql/psi/core/FixturesTest.kt
index 61c7268..685b29f 100644
--- a/core/src/test/kotlin/com/alecstrong/sql/psi/core/FixturesTest.kt
+++ b/core/src/test/kotlin/com/alecstrong/sql/psi/core/FixturesTest.kt
@@ -91,7 +91,8 @@ class FixturesTest(val dialect: DialectPreset, val name: String, val fixtureRoot
       DialectPreset.SQLITE_3_18 to arrayOf("src/test/fixtures", "src/test/fixtures_upsert_not_supported", "src/test/fixtures_sqlite_3_18"),
       DialectPreset.SQLITE_3_24 to arrayOf("src/test/fixtures", "src/test/fixtures_sqlite_3_24"),
       DialectPreset.SQLITE_3_25 to arrayOf("src/test/fixtures", "src/test/fixtures_sqlite_3_24", "src/test/fixtures_sqlite_3_25"),
-      DialectPreset.SQLITE_3_35 to arrayOf("src/test/fixtures", "src/test/fixtures_sqlite_3_24", "src/test/fixtures_sqlite_3_25", "src/test/fixtures_sqlite_3_35"),
+      DialectPreset.SQLITE_3_30 to arrayOf("src/test/fixtures", "src/test/fixtures_sqlite_3_24", "src/test/fixtures_sqlite_3_25", "src/test/fixtures_sqlite_3_30"),
+      DialectPreset.SQLITE_3_35 to arrayOf("src/test/fixtures", "src/test/fixtures_sqlite_3_24", "src/test/fixtures_sqlite_3_25", "src/test/fixtures_sqlite_3_30", "src/test/fixtures_sqlite_3_35"),
       DialectPreset.MYSQL to arrayOf("src/test/fixtures_mysql"),
       DialectPreset.HSQL to arrayOf("src/test/fixtures_hsql"),
       DialectPreset.POSTGRESQL to arrayOf("src/test/fixtures_postgresql")