Skip to content

Commit b04cbe9

Browse files
Added requested edits
1 parent 1801b2a commit b04cbe9

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

src/parser/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5199,7 +5199,6 @@ impl<'a> Parser<'a> {
51995199

52005200
// parse: [ argname ] argtype
52015201
let mut name = None;
5202-
let next_token = self.peek_token();
52035202
let mut data_type = self.parse_data_type()?;
52045203

52055204
// It may appear that the first token can be converted into a known
@@ -5210,8 +5209,16 @@ impl<'a> Parser<'a> {
52105209
// To check whether the first token is a name or a type, we need to
52115210
// peek the next token, which if it is another type keyword, then the
52125211
// first token is a name and not a type in itself.
5212+
let data_type_idx = self.get_current_index();
52135213
if let Some(next_data_type) = self.maybe_parse(|parser| parser.parse_data_type())? {
5214-
name = Some(Ident::new(next_token.to_string()));
5214+
let token = self.token_at(data_type_idx);
5215+
5216+
// We ensure that the token is a `Word` token, and not other special tokens.
5217+
if !matches!(token.token, Token::Word(_)) {
5218+
return self.expected("a name or type", token.clone());
5219+
}
5220+
5221+
name = Some(Ident::new(token.to_string()));
52155222
data_type = next_data_type;
52165223
}
52175224

tests/sqlparser_postgres.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
2222
#[macro_use]
2323
mod test_utils;
24+
2425
use helpers::attached_token::AttachedToken;
2526
use sqlparser::tokenizer::Span;
2627
use test_utils::*;
@@ -4264,6 +4265,51 @@ $$"#;
42644265
remote_connection: None,
42654266
})
42664267
);
4268+
4269+
let sql5 = r#"CREATE OR REPLACE FUNCTION foo(a TIMESTAMP WITH TIME ZONE, b VARCHAR) RETURNS BOOLEAN LANGUAGE plpgsql AS $$
4270+
BEGIN
4271+
RETURN TRUE;
4272+
END;
4273+
$$"#;
4274+
assert_eq!(
4275+
pg_and_generic().verified_stmt(sql5),
4276+
Statement::CreateFunction(CreateFunction {
4277+
or_alter: false,
4278+
or_replace: true,
4279+
temporary: false,
4280+
name: ObjectName::from(vec![Ident::new("foo")]),
4281+
args: Some(vec![
4282+
OperateFunctionArg::with_name(
4283+
"a",
4284+
DataType::Timestamp(None, TimezoneInfo::WithTimeZone)
4285+
),
4286+
OperateFunctionArg::with_name("b", DataType::Varchar(None)),
4287+
]),
4288+
return_type: Some(DataType::Boolean),
4289+
language: Some("plpgsql".into()),
4290+
behavior: None,
4291+
called_on_null: None,
4292+
parallel: None,
4293+
function_body: Some(CreateFunctionBody::AsBeforeOptions(Expr::Value(
4294+
(Value::DollarQuotedString(DollarQuotedString {
4295+
value: "\n BEGIN\n RETURN TRUE;\n END;\n ".to_owned(),
4296+
tag: None
4297+
}))
4298+
.with_empty_span()
4299+
))),
4300+
if_not_exists: false,
4301+
using: None,
4302+
determinism_specifier: None,
4303+
options: None,
4304+
remote_connection: None,
4305+
})
4306+
);
4307+
}
4308+
4309+
#[test]
4310+
fn parser_create_function_with_invalid_args() {
4311+
let sql = "CREATE FUNCTION add(function(struct<a,b> int64), b INTEGER) RETURNS INTEGER LANGUAGE SQL IMMUTABLE STRICT PARALLEL SAFE AS 'select $1 + $2;'";
4312+
assert!(pg().parse_sql_statements(sql).is_err(),);
42674313
}
42684314

42694315
#[test]

0 commit comments

Comments
 (0)