diff --git a/src/yugawara/analyzer/expression_analyzer.cpp b/src/yugawara/analyzer/expression_analyzer.cpp index 9d7ee44..af8336a 100644 --- a/src/yugawara/analyzer/expression_analyzer.cpp +++ b/src/yugawara/analyzer/expression_analyzer.cpp @@ -1455,6 +1455,30 @@ class engine { }); success = false; } + } else if (value.kind() == storage::column_value_kind::function) { + auto&& func = value.element(); + if (!func->parameter_types().empty()) { + report({ + code::inconsistent_elements, + "function call for default value must not have any arguments", + first_region(stmt.definition(), stmt), + }); + success = false; + } + if (auto r = type::is_assignment_convertible(func->return_type(), column.type()); + r != ternary::yes) { + report({ + code::inconsistent_type, + string_builder {} + << "function \"" << func->name() << "\" " + << "has inconsistent type (" << func->return_type() << ") " + << "for the column \"" << column.simple_name() << "\" " + << "(" << column.type() << ")" + << string_builder::to_string, + first_region(stmt.definition(), stmt), + }); + success = false; + } } } return success; diff --git a/test/yugawara/analyzer/expression_analyzer_statement_test.cpp b/test/yugawara/analyzer/expression_analyzer_statement_test.cpp index 5c311df..e567e09 100644 --- a/test/yugawara/analyzer/expression_analyzer_statement_test.cpp +++ b/test/yugawara/analyzer/expression_analyzer_statement_test.cpp @@ -6,10 +6,11 @@ #include #include + #include #include -#include +#include #include #include @@ -24,13 +25,16 @@ #include #include +#include + #include #include +#include + #include #include #include -#include namespace yugawara::analyzer { @@ -247,6 +251,41 @@ TEST_F(expression_analyzer_statement_test, create_table_default_value_sequence) EXPECT_TRUE(ok()); } +TEST_F(expression_analyzer_statement_test, create_table_default_value_function) { + auto func = std::make_shared(function::declaration { + function::declaration::minimum_builtin_function_id + 1, + "func", + t::int4(), + {}, + }); + auto schema = std::make_shared("s"); + auto table = std::make_shared(::takatori::util::clone_tag, storage::table { + "T0", + { + { "C0", t::int4() }, + { + "C1", + t::int4(), + variable::nullable, + { func }, + }, + { "C2", t::int4() }, + }, + }); + auto index = std::make_shared(storage::index { + table, + "I0", + }); + statement::create_table stmt { + bindings(schema), + bindings(table), + bindings(index), + }; + auto b = analyzer.resolve(stmt, true); + ASSERT_TRUE(b); + EXPECT_TRUE(ok()); +} + TEST_F(expression_analyzer_statement_test, create_table_default_value_immediate_inconsistent) { auto schema = std::make_shared("s"); auto table = std::make_shared(::takatori::util::clone_tag, storage::table { @@ -308,4 +347,76 @@ TEST_F(expression_analyzer_statement_test, create_table_default_value_sequence_i EXPECT_FALSE(ok()); } +TEST_F(expression_analyzer_statement_test, create_table_default_value_function_inconsistent_return_type) { + auto func = std::make_shared(function::declaration { + function::declaration::minimum_builtin_function_id + 1, + "func", + t::int4(), + {}, + }); + auto schema = std::make_shared("s"); + auto table = std::make_shared(::takatori::util::clone_tag, storage::table { + "T0", + { + { "C0", t::int4() }, + { + "C1", + t::date {}, + variable::nullable, + { func }, + }, + { "C2", t::int4() }, + }, + }); + auto index = std::make_shared(storage::index { + table, + "I0", + }); + statement::create_table stmt { + bindings(schema), + bindings(table), + bindings(index), + }; + auto b = analyzer.resolve(stmt, true); + EXPECT_FALSE(b); + EXPECT_FALSE(ok()); +} + +TEST_F(expression_analyzer_statement_test, create_table_default_value_function_inconsistent_parameters) { + auto func = std::make_shared(function::declaration { + function::declaration::minimum_builtin_function_id + 1, + "func", + t::int4(), + { + t::int4(), + }, + }); + auto schema = std::make_shared("s"); + auto table = std::make_shared(::takatori::util::clone_tag, storage::table { + "T0", + { + { "C0", t::int4() }, + { + "C1", + t::int4(), + variable::nullable, + { func }, + }, + { "C2", t::int4() }, + }, + }); + auto index = std::make_shared(storage::index { + table, + "I0", + }); + statement::create_table stmt { + bindings(schema), + bindings(table), + bindings(index), + }; + auto b = analyzer.resolve(stmt, true); + EXPECT_FALSE(b); + EXPECT_FALSE(ok()); +} + } // namespace yugawara::analyzer