Repository: AlecStrong/sql-psi
Pull request #366 (2022-04-07 21:40:50)

Make sure synthesized columns also appear in from statements
Closes https://github.com/AlecStrong/sql-psi/issues/142


Patch:
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/QueryElement.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/QueryElement.kt
index d518f6f..e967baa 100644
--- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/QueryElement.kt
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/QueryElement.kt
@@ -35,7 +35,7 @@ interface QueryElement : PsiElement {
     constructor(column: PsiElement) : this(columns = listOf(QueryColumn(column)))
 
     override fun toString(): String {
-      return "${table?.name} : [${columns.joinToString { it.element.text }}]"
+      return "${table?.name} : [${columns.joinToString { it.element.text }} [${synthesizedColumns.joinToString { it.acceptableValues.toString() }}]]"
     }
   }
 
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/ColumnAliasMixin.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/ColumnAliasMixin.kt
index 80524a3..dd5cf66 100644
--- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/ColumnAliasMixin.kt
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/ColumnAliasMixin.kt
@@ -19,7 +19,7 @@ internal abstract class ColumnAliasMixin(
   override fun source(): PsiElement {
     parent.let {
       return when (it) {
-        is ResultColumnMixin -> it.expr!!
+        is ResultColumnMixin -> it
 
         is SqlCteTableName -> {
           val index = it.columnAliasList.indexOf(this)
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/TableOrSubqueryMixin.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/TableOrSubqueryMixin.kt
index 851f494..4593aff 100644
--- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/TableOrSubqueryMixin.kt
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/TableOrSubqueryMixin.kt
@@ -17,7 +17,7 @@ internal abstract class TableOrSubqueryMixin(
         return@lazy emptyList<QueryResult>()
       }
       tableAlias?.let { alias ->
-        return@lazy listOf(QueryResult(alias, result.flatMap { it.columns }))
+        return@lazy listOf(QueryResult(alias, result.flatMap { it.columns }, result.flatMap { it.synthesizedColumns }))
       }
       return@lazy result
     }
diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/sql.bnf b/core/src/main/kotlin/com/alecstrong/sql/psi/core/sql.bnf
index ab21b4d..b138938 100644
--- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/sql.bnf
+++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/sql.bnf
@@ -57,7 +57,7 @@ stmt_list ::= ( stmt ';' ) * {
 }
 stmt ::= [ EXPLAIN [ QUERY PLAN ] ] ( alter_table_stmt | analyze_stmt | attach_stmt | begin_stmt | commit_stmt | create_index_stmt | create_table_stmt | create_trigger_stmt | create_view_stmt |
                                           create_virtual_table_stmt | delete_stmt_limited | detach_stmt | drop_index_stmt | drop_table_stmt | drop_trigger_stmt | drop_view_stmt | insert_stmt |
-                                          pragma_stmt | reindex_stmt | release_stmt | rollback_stmt | savepoint_stmt | compound_select_stmt | update_stmt_limited | vacuum_stmt
+                                          pragma_stmt | reindex_stmt | release_stmt | rollback_stmt | savepoint_stmt | compound_select_stmt | update_stmt_limited | vacuum_stmt | extension_stmt
                                         ) {
   recoverWhile=sql_stmt_recovery
   pin = 2
@@ -116,7 +116,8 @@ column_def ::= [ javadoc ] column_name column_type ( column_constraint ) * {
 }
 column_type ::= type_name
 type_name ::= identifier [ '(' signed_number ')' | '(' signed_number ',' signed_number ')' ]
-column_constraint ::= [ CONSTRAINT identifier ] ( PRIMARY KEY [ ASC | DESC ] conflict_clause [ AUTOINCREMENT ] | NOT NULL conflict_clause | UNIQUE conflict_clause | check_constraint | default_constraint | COLLATE collation_name | foreign_key_clause )
+column_constraint ::= [ CONSTRAINT identifier ] ( PRIMARY KEY [ ASC | DESC ] conflict_clause [ AUTOINCREMENT ] | NOT NULL conflict_clause | UNIQUE conflict_clause | check_constraint | default_constraint | COLLATE collation_name | foreign_key_clause | generated_clause )
+generated_clause ::= [ GENERATED ] ALWAYS AS '(' expr ')'
 check_constraint ::= CHECK '(' expr ')'
 default_constraint ::= DEFAULT ( signed_number | literal_value | '(' expr ')' )
 signed_number ::= [ '+' | '-' ] numeric_literal
@@ -225,6 +226,7 @@ expr ::= ( raise_expr
 
 other_expr ::= extension_expr
 extension_expr ::= NULL
+extension_stmt ::= NULL
 literal_expr ::= literal_value
 bind_expr ::= bind_parameter
 column_expr ::= [ database_name '.' table_name '.' | table_name '.' ] column_name
@@ -255,7 +257,7 @@ binary_and_expr ::= expr AND expr {
 binary_or_expr ::= expr OR expr {
   implements = "com.alecstrong.sql.psi.core.psi.SqlBinaryExpr"
 }
-function_expr ::= function_name '(' [ [ DISTINCT ] expr ( ( ',' | FROM | FOR ) expr ) * | '*' ] ')'
+function_expr ::= function_name '(' [ [ DISTINCT ] expr ( ( ',' | FROM | FOR | SEPARATOR ) expr ) * | '*' ] ')'
 paren_expr ::= '(' expr ')' {
   pin = 1
 }


Test patch:
diff --git a/test-fixtures/src/main/resources/fixtures/rowid-orderby/Test.s b/test-fixtures/src/main/resources/fixtures/rowid-orderby/Test.s
new file mode 100644
index 0000000..90b412a
--- /dev/null
+++ b/test-fixtures/src/main/resources/fixtures/rowid-orderby/Test.s
@@ -0,0 +1,14 @@
+CREATE TABLE Test1(id TEXT);
+CREATE TABLE Test2(id TEXT);
+
+SELECT t1.*
+FROM Test1 t1
+WHERE t1.rowid IS NOT NULL
+ORDER BY t1.rowid ASC
+LIMIT 1;
+
+SELECT t1.*, t2.* FROM Test1 t1
+JOIN Test2 t2 ON t1.id = t2.id
+WHERE t1.id = 'something good'
+ORDER BY t1.rowid ASC
+LIMIT 1;
\ No newline at end of file