@@ -55,6 +55,7 @@ pub enum IsLateral {
5555 Lateral ,
5656 NotLateral ,
5757}
58+ use crate :: ast:: Statement :: CreateVirtualTable ;
5859use IsLateral :: * ;
5960
6061impl From < TokenizerError > for ParserError {
@@ -986,16 +987,35 @@ impl Parser {
986987 self . parse_create_view ( )
987988 } else if self . parse_keyword ( Keyword :: EXTERNAL ) {
988989 self . parse_create_external_table ( )
990+ } else if self . parse_keyword ( Keyword :: VIRTUAL ) {
991+ self . parse_create_virtual_table ( )
989992 } else if self . parse_keyword ( Keyword :: SCHEMA ) {
990993 self . parse_create_schema ( )
991994 } else {
992- self . expected (
993- "TABLE, VIEW, INDEX or SCHEMA after CREATE" ,
994- self . peek_token ( ) ,
995- )
995+ self . expected ( "an object type after CREATE" , self . peek_token ( ) )
996996 }
997997 }
998998
999+ /// SQLite-specific `CREATE VIRTUAL TABLE`
1000+ pub fn parse_create_virtual_table ( & mut self ) -> Result < Statement , ParserError > {
1001+ self . expect_keyword ( Keyword :: TABLE ) ?;
1002+ let if_not_exists = self . parse_keywords ( & [ Keyword :: IF , Keyword :: NOT , Keyword :: EXISTS ] ) ;
1003+ let table_name = self . parse_object_name ( ) ?;
1004+ self . expect_keyword ( Keyword :: USING ) ?;
1005+ let module_name = self . parse_identifier ( ) ?;
1006+ // SQLite docs note that module "arguments syntax is sufficiently
1007+ // general that the arguments can be made to appear as column
1008+ // definitions in a traditional CREATE TABLE statement", but
1009+ // we don't implement that.
1010+ let module_args = self . parse_parenthesized_column_list ( Optional ) ?;
1011+ Ok ( CreateVirtualTable {
1012+ name : table_name,
1013+ if_not_exists,
1014+ module_name,
1015+ module_args,
1016+ } )
1017+ }
1018+
9991019 pub fn parse_create_schema ( & mut self ) -> Result < Statement , ParserError > {
10001020 let schema_name = self . parse_object_name ( ) ?;
10011021 Ok ( Statement :: CreateSchema { schema_name } )
0 commit comments