Added support for ALTER OPERATOR FAMILY syntax (#2125)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run

This commit is contained in:
Luca Cappelletti 2025-12-18 05:34:48 +01:00 committed by GitHub
parent f84887d004
commit d78dbc97a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 778 additions and 25 deletions

View file

@ -23,15 +23,11 @@
mod test_utils;
use helpers::attached_token::AttachedToken;
use sqlparser::ast::{
DataType, DropBehavior, DropOperator, DropOperatorClass, DropOperatorSignature,
};
use sqlparser::tokenizer::Span;
use test_utils::*;
use sqlparser::ast::*;
use sqlparser::dialect::{GenericDialect, PostgreSqlDialect};
use sqlparser::parser::ParserError;
use sqlparser::tokenizer::Span;
use test_utils::*;
#[test]
fn parse_create_table_generated_always_as_identity() {
@ -7145,6 +7141,396 @@ fn parse_alter_operator() {
);
}
#[test]
fn parse_alter_operator_family() {
// Test ALTER OPERATOR FAMILY ... ADD OPERATOR
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 1 < (INT4, INT2)";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("integer_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::Add {
items: vec![OperatorFamilyItem::Operator {
strategy_number: 1,
operator_name: ObjectName::from(vec![Ident::new("<")]),
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
purpose: None,
}],
},
})
);
// Test ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR SEARCH
let sql =
"ALTER OPERATOR FAMILY text_ops USING btree ADD OPERATOR 1 @@ (TEXT, TEXT) FOR SEARCH";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("text_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::Add {
items: vec![OperatorFamilyItem::Operator {
strategy_number: 1,
operator_name: ObjectName::from(vec![Ident::new("@@")]),
op_types: vec![DataType::Text, DataType::Text],
purpose: Some(OperatorPurpose::ForSearch),
}],
},
})
);
// Test ALTER OPERATOR FAMILY ... ADD FUNCTION
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree ADD FUNCTION 1 btint42cmp(INT4, INT2)";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("integer_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::Add {
items: vec![OperatorFamilyItem::Function {
support_number: 1,
op_types: None,
function_name: ObjectName::from(vec![Ident::new("btint42cmp")]),
argument_types: vec![DataType::Int4(None), DataType::Int2(None)],
}],
},
})
);
// Test ALTER OPERATOR FAMILY ... DROP OPERATOR
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree DROP OPERATOR 1 (INT4, INT2)";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("integer_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::Drop {
items: vec![OperatorFamilyDropItem::Operator {
strategy_number: 1,
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
}],
},
})
);
// Test ALTER OPERATOR FAMILY ... DROP FUNCTION
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree DROP FUNCTION 1 (INT4, INT2)";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("integer_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::Drop {
items: vec![OperatorFamilyDropItem::Function {
support_number: 1,
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
}],
},
})
);
// Test ALTER OPERATOR FAMILY ... RENAME TO
let sql = "ALTER OPERATOR FAMILY old_ops USING btree RENAME TO new_ops";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("old_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::RenameTo {
new_name: ObjectName::from(vec![Ident::new("new_ops")]),
},
})
);
// Test ALTER OPERATOR FAMILY ... OWNER TO
let sql = "ALTER OPERATOR FAMILY my_ops USING btree OWNER TO joe";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("my_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::OwnerTo(Owner::Ident(Ident::new("joe"))),
})
);
// Test ALTER OPERATOR FAMILY ... SET SCHEMA
let sql = "ALTER OPERATOR FAMILY my_ops USING btree SET SCHEMA new_schema";
assert_eq!(
pg_and_generic().verified_stmt(sql),
Statement::AlterOperatorFamily(AlterOperatorFamily {
name: ObjectName::from(vec![Ident::new("my_ops")]),
using: Ident::new("btree"),
operation: AlterOperatorFamilyOperation::SetSchema {
schema_name: ObjectName::from(vec![Ident::new("new_schema")]),
},
})
);
// Test error cases
// Missing USING clause
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops ADD OPERATOR 1 < (INT4, INT2)")
.is_err());
// Invalid operation
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree INVALID_OPERATION")
.is_err());
// Missing operator name in ADD OPERATOR
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 (INT4, INT2)"
)
.is_err());
// Missing function name in ADD FUNCTION
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2)"
)
.is_err());
// Missing parentheses in DROP OPERATOR
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 INT4, INT2")
.is_err());
// Invalid operator name (empty)
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 (INT4, INT2)"
)
.is_err());
// Invalid operator name (special characters)
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 @#$ (INT4, INT2)"
)
.is_err());
// Negative strategy number
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR -1 < (INT4, INT2)"
)
.is_err());
// Non-integer strategy number
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1.5 < (INT4, INT2)"
)
.is_err());
// Missing closing parenthesis in operator types
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2"
)
.is_err());
// Missing opening parenthesis in operator types
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < INT4, INT2)"
)
.is_err());
// Empty operator types
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < ()")
.is_err());
// Invalid data type (using punctuation)
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (@#$%, INT2)"
)
.is_err());
// Incomplete FOR clause
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR"
)
.is_err());
// Invalid FOR clause keyword
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR INVALID"
)
.is_err());
// FOR ORDER BY without sort family
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR ORDER BY"
)
.is_err());
// Missing function name in ADD FUNCTION
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2)"
)
.is_err());
// Invalid function name
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 123invalid(INT4, INT2)"
)
.is_err());
// Negative support number
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION -1 func(INT4, INT2)"
)
.is_err());
// Non-integer support number
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1.5 func(INT4, INT2)"
)
.is_err());
// Missing closing parenthesis in function operator types
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2 func()"
)
.is_err());
// Missing closing parenthesis in function arguments
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 func(INT4, INT2"
)
.is_err());
// Invalid data type in function arguments
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 func(@#$%, INT2)"
)
.is_err());
// DROP OPERATOR with FOR clause (not allowed)
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 (INT4, INT2) FOR SEARCH"
)
.is_err());
// DROP FUNCTION with function arguments (not allowed)
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree DROP FUNCTION 1 (INT4, INT2) func(INT4)"
)
.is_err());
// Multiple ADD items with error in middle
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2), INVALID_ITEM"
)
.is_err());
// Multiple DROP items with error in middle
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 (INT4, INT2), INVALID_ITEM"
)
.is_err());
// RENAME TO with invalid new name
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree RENAME TO 123invalid")
.is_err());
// OWNER TO with invalid owner
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree OWNER TO 123invalid")
.is_err());
// SET SCHEMA with invalid schema name
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree SET SCHEMA 123invalid")
.is_err());
// Schema-qualified operator family name with invalid schema
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY 123invalid.my_ops USING btree ADD OPERATOR 1 < (INT4, INT2)"
)
.is_err());
// Missing operator family name
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY USING btree ADD OPERATOR 1 < (INT4, INT2)")
.is_err());
// Extra tokens at end
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) EXTRA"
)
.is_err());
// Incomplete statement
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD")
.is_err());
// Very long numbers
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 999999999999999999999 < (INT4, INT2)")
.is_err());
// Multiple FOR clauses
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR SEARCH FOR ORDER BY sort_family")
.is_err());
// FOR SEARCH with extra tokens
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR SEARCH EXTRA")
.is_err());
// FOR ORDER BY with invalid sort family
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR ORDER BY 123invalid")
.is_err());
// Function with empty operator types but missing function args parens
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 () func")
.is_err());
// Function with mismatched parentheses
assert!(pg()
.parse_sql_statements(
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4 func(INT2"
)
.is_err());
// DROP with empty types
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 ()")
.is_err());
// DROP FUNCTION with empty types
assert!(pg()
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP FUNCTION 1 ()")
.is_err());
}
#[test]
fn parse_drop_operator_family() {
for if_exists in [true, false] {