mirror of
				https://github.com/apache/datafusion-sqlparser-rs.git
				synced 2025-10-30 23:07:04 +00:00 
			
		
		
		
	SupportSELECT AS VALUE and SELECT AS STRUCT for BigQuery (#1135)
				
					
				
			This commit is contained in:
		
							parent
							
								
									6a9b6f547d
								
							
						
					
					
						commit
						1cf6585649
					
				
					 10 changed files with 89 additions and 10 deletions
				
			
		|  | @ -44,8 +44,8 @@ pub use self::query::{ | |||
|     JsonTableColumnErrorHandling, LateralView, LockClause, LockType, NamedWindowDefinition, | ||||
|     NonBlock, Offset, OffsetRows, OrderByExpr, Query, RenameSelectItem, ReplaceSelectElement, | ||||
|     ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, Table, | ||||
|     TableAlias, TableFactor, TableVersion, TableWithJoins, Top, TopQuantity, Values, | ||||
|     WildcardAdditionalOptions, With, | ||||
|     TableAlias, TableFactor, TableVersion, TableWithJoins, Top, TopQuantity, ValueTableMode, | ||||
|     Values, WildcardAdditionalOptions, With, | ||||
| }; | ||||
| pub use self::value::{ | ||||
|     escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value, | ||||
|  |  | |||
|  | @ -245,11 +245,18 @@ pub struct Select { | |||
|     pub named_window: Vec<NamedWindowDefinition>, | ||||
|     /// QUALIFY (Snowflake)
 | ||||
|     pub qualify: Option<Expr>, | ||||
|     /// BigQuery syntax: `SELECT AS VALUE | SELECT AS STRUCT`
 | ||||
|     pub value_table_mode: Option<ValueTableMode>, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for Select { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         write!(f, "SELECT")?; | ||||
| 
 | ||||
|         if let Some(value_table_mode) = self.value_table_mode { | ||||
|             write!(f, " {value_table_mode}")?; | ||||
|         } | ||||
| 
 | ||||
|         if let Some(ref distinct) = self.distinct { | ||||
|             write!(f, " {distinct}")?; | ||||
|         } | ||||
|  | @ -1574,3 +1581,24 @@ impl fmt::Display for JsonTableColumnErrorHandling { | |||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// BigQuery supports ValueTables which have 2 modes:
 | ||||
| /// `SELECT AS STRUCT`
 | ||||
| /// `SELECT AS VALUE`
 | ||||
| /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#value_tables>
 | ||||
| #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] | ||||
| #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||||
| #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] | ||||
| pub enum ValueTableMode { | ||||
|     AsStruct, | ||||
|     AsValue, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for ValueTableMode { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match self { | ||||
|             ValueTableMode::AsStruct => write!(f, "AS STRUCT"), | ||||
|             ValueTableMode::AsValue => write!(f, "AS VALUE"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6826,6 +6826,19 @@ impl<'a> Parser<'a> { | |||
|     /// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`),
 | ||||
|     /// assuming the initial `SELECT` was already consumed
 | ||||
|     pub fn parse_select(&mut self) -> Result<Select, ParserError> { | ||||
|         let value_table_mode = | ||||
|             if dialect_of!(self is BigQueryDialect) && self.parse_keyword(Keyword::AS) { | ||||
|                 if self.parse_keyword(Keyword::VALUE) { | ||||
|                     Some(ValueTableMode::AsValue) | ||||
|                 } else if self.parse_keyword(Keyword::STRUCT) { | ||||
|                     Some(ValueTableMode::AsStruct) | ||||
|                 } else { | ||||
|                     self.expected("VALUE or STRUCT", self.peek_token())? | ||||
|                 } | ||||
|             } else { | ||||
|                 None | ||||
|             }; | ||||
| 
 | ||||
|         let distinct = self.parse_all_or_distinct()?; | ||||
| 
 | ||||
|         let top = if self.parse_keyword(Keyword::TOP) { | ||||
|  | @ -6962,6 +6975,7 @@ impl<'a> Parser<'a> { | |||
|             having, | ||||
|             named_window: named_windows, | ||||
|             qualify, | ||||
|             value_table_mode, | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukasz Stefaniak
						Lukasz Stefaniak