fn parse_source_columns(&mut self) -> Result<(Vec<Ident>, Option<KeyConstraint>), ParserError> {
        if self.consume_token(&Token::LParen) {
            let mut columns = vec![];
            let mut key_constraints = vec![];
            loop {
                let pos = self.peek_pos();
                if let Some(key_constraint) = self.parse_key_constraint()? {
                    if !key_constraints.is_empty() {
                        return parser_err!(self, pos, "Multiple key constraints not allowed");
                    }
                    key_constraints.push(key_constraint);
                } else {
                    columns.push(self.parse_identifier()?);
                }
                if !self.consume_token(&Token::Comma) {
                    break;
                }
            }
            self.expect_token(&Token::RParen)?;
            Ok((columns, key_constraints.into_iter().next()))
        } else {
            Ok((vec![], None))
        }
    }
/// Parses the column section of a CREATE SOURCE statement which can be
/// empty or a comma-separated list of column identifiers and a single key
/// constraint, e.g.
///
/// (col_0, col_i, ..., col_n, key_constraint)
Parses the column section of a CREATE SOURCE statement which can be
empty or a comma-separated list of column identifiers and a single key
constraint, e.g.


Parses the column section of a CREATE SOURCE statement which can be empty or a comma - separated list of column identifiers and a single key constraint e . g .
fn parse_source_columns(&mut self) -> Result<(Vec<Ident>, Option<KeyConstraint>), ParserError> {
        if self.consume_token(&Token::LParen) {
            let mut columns = vec![];
            let mut key_constraints = vec![];
            loop {
                let pos = self.peek_pos();
                if let Some(key_constraint) = self.parse_key_constraint()? {
                    if !key_constraints.is_empty() {
                        return parser_err!(self, pos, "Multiple key constraints not allowed");
                    }
                    key_constraints.push(key_constraint);
                } else {
                    columns.push(self.parse_identifier()?);
                }
                if !self.consume_token(&Token::Comma) {
                    break;
                }
            }
            self.expect_token(&Token::RParen)?;
            Ok((columns, key_constraints.into_iter().next()))
        } else {
            Ok((vec![], None))
        }
    }
fn parse_source_columns ( & mut self ) -> Result < ( Vec < Ident > , Option < KeyConstraint > ) , ParserError > { if self . consume_token ( & Token :: LParen ) { let mut columns = vec ! [ ] ; let mut key_constraints = vec ! [ ] ; loop { let pos = self . peek_pos ( ) ; if let Some ( key_constraint ) = self . parse_key_constraint ( ) ? { if ! key_constraints . is_empty ( ) { return parser_err ! ( self pos " " ) ; } key_constraints . push ( key_constraint ) ; } else { columns . push ( self . parse_identifier ( ) ? ) ; } if ! self . consume_token ( & Token :: Comma ) { break ; } } self . expect_token ( & Token :: RParen ) ? ; Ok ( ( columns , key_constraints . into_iter ( ) . next ( ) ) ) } else { Ok ( ( vec ! [ ] , None ) ) } }
Parses the column section of a CREATE SOURCE statement which can be
empty or a comma-separated list of column identifiers and a single key
constraint, e.g.
Parses the column section of a CREATE SOURCE statement which can be empty or a comma - separated list of column identifiers and a single key constraint e . g .
&mut self
&mut self