diff --git a/src/postgres_deparse.c b/src/postgres_deparse.c index d4d8237a..f2a80a51 100644 --- a/src/postgres_deparse.c +++ b/src/postgres_deparse.c @@ -4478,7 +4478,7 @@ static void deparseTypeName(DeparseState *state, TypeName *type_name) else if (IsA(lfirst(lc), ColumnRef)) deparseColumnRef(state, lfirst(lc)); else - Assert(false); + elog(ERROR, "deparse: unsupported typmod node type: %u", nodeTag(lfirst(lc))); if (lnext(type_name->typmods, lc)) deparseAppendStringInfoString(state, ", "); diff --git a/test/deparse.c b/test/deparse.c index 5ffb1db3..51ca77eb 100644 --- a/test/deparse.c +++ b/test/deparse.c @@ -127,6 +127,42 @@ int run_test(const char *query, bool compare_query_text, bool pretty_print) { return ret_code; } +int run_test_expect_deparse_error(const char *query, const char *expected_message_substring) { + PgQueryProtobufParseResult parse_result = pg_query_parse_protobuf(query); + if (parse_result.error) { + printf("\nERROR for \"%s\"\n unexpected parse error: %s\n", query, parse_result.error->message); + pg_query_free_protobuf_parse_result(parse_result); + return EXIT_FAILURE; + } + + PgQueryDeparseResult deparse_result = pg_query_deparse_protobuf(parse_result.parse_tree); + if (!deparse_result.error) { + printf("\nERROR for \"%s\"\n expected deparse error, got: %s\n", + query, + deparse_result.query); + pg_query_free_deparse_result(deparse_result); + pg_query_free_protobuf_parse_result(parse_result); + return EXIT_FAILURE; + } + + if (expected_message_substring != NULL && + strstr(deparse_result.error->message, expected_message_substring) == NULL) { + printf("\nERROR for \"%s\"\n expected deparse error containing \"%s\"\n actual: %s\n", + query, + expected_message_substring, + deparse_result.error->message); + pg_query_free_deparse_result(deparse_result); + pg_query_free_protobuf_parse_result(parse_result); + return EXIT_FAILURE; + } + + printf("."); + + pg_query_free_deparse_result(deparse_result); + pg_query_free_protobuf_parse_result(parse_result); + return EXIT_SUCCESS; +} + int run_tests_from_file(const char * filename, bool compare_query_text, bool pretty_print) { char *sample_buffer; struct stat sample_stat; @@ -604,6 +640,13 @@ const char* plpgsqlRegressFilenames[] = }; size_t plpgsqlRegressFilenameCount = sizeof(plpgsqlRegressFilenames) / sizeof(plpgsqlRegressFilenames[0]); +const char* deparseErrorTests[] = { + "CREATE TABLE t0 (foo ENUM8('a' = 1, 2))", + "CREATE TABLE t0 (foo ENUM8('a' = 1, 'b' = 2), bar ENUM16('a' = 1, 'b' = 2), baz ENUM('a', 'b'))", + "SELECT 1::enum8('a' = 1, 2)" +}; +size_t deparseErrorTestsLength = sizeof(deparseErrorTests) / sizeof(deparseErrorTests[0]); + int main() { size_t i; int ret_code = EXIT_SUCCESS; @@ -637,6 +680,13 @@ int main() { ret_code = test_ret_code; } + printf("\ndeparse_error.sql\n"); + for (i = 0; i < deparseErrorTestsLength; i += 1) { + test_ret_code = run_test_expect_deparse_error(deparseErrorTests[i], "unsupported typmod node type"); + if (test_ret_code != EXIT_SUCCESS) + ret_code = test_ret_code; + } + for (i = 0; i < regressFilenameCount; i += 1) { printf("\n%s\n", regressFilenames[i]); char *filename = malloc(sizeof(char) * strlen("test/sql/postgres_regress/") + strlen(regressFilenames[i]) + 1);