Skip to content

CREATE PROPERTY GRAPH error #213

@arron-lyu

Description

@arron-lyu

What happens?

I tested duckdb-pgq(commit f27ae41), but crashed。

D attach 'finbench.duckdb';
D use finbench;
D CREATE PROPERTY GRAPH finbench
  VERTEX TABLES (
      Person,
      Account
  )
  EDGE TABLES (
      AccountTransferAccount
          SOURCE KEY (fromId) REFERENCES Account (accountId)
          DESTINATION KEY (toId) REFERENCES Account (accountId)
          LABEL Transfer,
      PersonOwnAccount
          SOURCE KEY (personId) REFERENCES Person (personId)
          DESTINATION KEY (accountId) REFERENCES Account (accountId)
          LABEL PersonOwn
  );
=================================================================
==82734==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6130000e6200 at pc 0x000103cd8314 bp 0x00016ced0800 sp 0x00016ced07f8
READ of size 8 at 0x6130000e6200 thread T0
    #0 0x000103cd8310 in std::__1::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>>::get[abi:ne190102]() const unique_ptr.h:274
    #1 0x000103c242ac in duckdb::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>, true>::operator->() const unique_ptr.hpp:40
    #2 0x000103e61f74 in duckdb::Binder::BindCreateViewInfo(duckdb::CreateViewInfo&) bind_create.cpp:178
    #3 0x000103e71220 in duckdb::Binder::Bind(duckdb::CreateStatement&) bind_create.cpp:515
    #4 0x00010442d9f4 in duckdb::Binder::Bind(duckdb::SQLStatement&) binder.cpp:91
    #5 0x00010446b6ac in duckdb::Planner::CreatePlan(duckdb::SQLStatement&) planner.cpp:45
    #6 0x00010447060c in duckdb::Planner::CreatePlan(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>) planner.cpp:148
    #7 0x00010a78d04c in duckdb::ClientContext::CreatePreparedStatementInternal(duckdb::ClientContextLock&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::optional_ptr<std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, duckdb::BoundParameterData, duckdb::CaseInsensitiveStringHashFunction, duckdb::CaseInsensitiveStringEquality, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, duckdb::BoundParameterData>>>, true>) client_context.cpp:378
    #8 0x00010a791a0c in duckdb::ClientContext::CreatePreparedStatement(duckdb::ClientContextLock&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::optional_ptr<std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, duckdb::BoundParameterData, duckdb::CaseInsensitiveStringHashFunction, duckdb::CaseInsensitiveStringEquality, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, duckdb::BoundParameterData>>>, true>, duckdb::PreparedStatementMode) client_context.cpp:460
    #9 0x00010a7a5b88 in duckdb::ClientContext::PendingStatementInternal(duckdb::ClientContextLock&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::PendingQueryParameters const&) client_context.cpp:793
    #10 0x00010a7acf58 in duckdb::ClientContext::PendingStatementOrPreparedStatement(duckdb::ClientContextLock&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::shared_ptr<duckdb::PreparedStatementData, true>&, duckdb::PendingQueryParameters const&) client_context.cpp:911
    #11 0x00010a7a360c in duckdb::ClientContext::PendingStatementOrPreparedStatementInternal(duckdb::ClientContextLock&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::shared_ptr<duckdb::PreparedStatementData, true>&, duckdb::PendingQueryParameters const&) client_context.cpp:884
    #12 0x00010a7a7f2c in duckdb::ClientContext::PendingQueryInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, duckdb::PendingQueryParameters const&, bool) client_context.cpp:1098
    #13 0x00010a7b2fdc in duckdb::ClientContext::PendingQuery(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, duckdb::BoundParameterData, duckdb::CaseInsensitiveStringHashFunction, duckdb::CaseInsensitiveStringEquality, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, duckdb::BoundParameterData>>>&, bool) client_context.cpp:1085
    #14 0x00010a7ae77c in duckdb::ClientContext::PendingQuery(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, bool) client_context.cpp:1043
    #15 0x00010a7e35e8 in duckdb::Connection::PendingQuery(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, bool) connection.cpp:119
    #16 0x00010308f2b4 in duckdb_shell_sqlite3_prepare_v2 sqlite3_api_wrapper.cpp:226
    #17 0x000102faf2b8 in duckdb_shell::ShellState::ExecuteSQL(char const*, char**) shell.cpp:1787
    #18 0x000102fddc08 in duckdb_shell::ShellState::RunOneSqlLine(duckdb_shell::InputMode, char*) shell.cpp:4467
    #19 0x000102fd6a44 in duckdb_shell::ShellState::ProcessInput(duckdb_shell::InputMode) shell.cpp:4582
    #20 0x000102fe2f7c in main shell.cpp:5224
    #21 0x0001896ceb94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)

0x6130000e6200 is located 8 bytes after 376-byte region [0x6130000e6080,0x6130000e61f8)
allocated by thread T0 here:
    #0 0x0001225776e4 in _Znwm+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x4b6e4)
    #1 0x00010471b3ec in duckdb::TemplatedUniqueIf<duckdb::CreatePropertyGraphInfo, true>::templated_unique_single_t duckdb::make_uniq<duckdb::CreatePropertyGraphInfo>() helper.hpp:65
    #2 0x00010499c8a4 in duckdb::Transformer::TransformCreatePropertyGraph(duckdb_libpgquery::PGCreatePropertyGraphStmt&) transform_create_property_graph.cpp:143
    #3 0x000104b12968 in duckdb::Transformer::TransformStatementInternal(duckdb_libpgquery::PGNode&) transformer.cpp:221
    #4 0x000104b0f230 in duckdb::Transformer::TransformStatement(duckdb_libpgquery::PGNode&) transformer.cpp:59
    #5 0x000104b104e4 in duckdb::Transformer::TransformStatementInternal(duckdb_libpgquery::PGNode&) transformer.cpp:139
    #6 0x000104b0f230 in duckdb::Transformer::TransformStatement(duckdb_libpgquery::PGNode&) transformer.cpp:59
    #7 0x000104aca7c8 in duckdb::Transformer::TransformParseTree(duckdb_libpgquery::PGList*, duckdb::vector<duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>, true>&) transformer.cpp:33
    #8 0x000104ac6f88 in duckdb::Parser::ParseQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&) parser.cpp:249
    #9 0x00010308e13c in duckdb_shell_sqlite3_prepare_v2 sqlite3_api_wrapper.cpp:183
    #10 0x000102faf2b8 in duckdb_shell::ShellState::ExecuteSQL(char const*, char**) shell.cpp:1787
    #11 0x000102fddc08 in duckdb_shell::ShellState::RunOneSqlLine(duckdb_shell::InputMode, char*) shell.cpp:4467
    #12 0x000102fd6a44 in duckdb_shell::ShellState::ProcessInput(duckdb_shell::InputMode) shell.cpp:4582
    #13 0x000102fe2f7c in main shell.cpp:5224
    #14 0x0001896ceb94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)

SUMMARY: AddressSanitizer: heap-buffer-overflow unique_ptr.h:274 in std::__1::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>>::get[abi:ne190102]() const
Shadow bytes around the buggy address:
  0x6130000e5f80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6130000e6000: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x6130000e6080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000e6100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000e6180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
=>0x6130000e6200:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6130000e6280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6130000e6300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6130000e6380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6130000e6400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6130000e6480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==82734==ABORTING

I found that the code at bind_create.cpp:512: auto &base = stmt.info->Cast<CreateViewInfo>();, stmt.info is CreatePropertyGraphInfo, and CreatePropertyGraphInfo is not inherit from CreateViewInfo, so Cast failed.

To Reproduce

D attach 'finbench.duckdb';
D use finbench;
D CREATE PROPERTY GRAPH finbench
  VERTEX TABLES (
      Person,
      Account
  )
  EDGE TABLES (
      AccountTransferAccount
          SOURCE KEY (fromId) REFERENCES Account (accountId)
          DESTINATION KEY (toId) REFERENCES Account (accountId)
          LABEL Transfer,
      PersonOwnAccount
          SOURCE KEY (personId) REFERENCES Person (personId)
          DESTINATION KEY (accountId) REFERENCES Account (accountId)
          LABEL PersonOwn
  );

OS:

MacOS, M1

DuckDB Version:

duckdb-pgq(f27ae41)

DuckDB Client:

shell

Hardware:

No response

Full Name:

Arron

Affiliation:

YaSpeed

Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?

  • Yes, I have

Did you include all code required to reproduce the issue?

  • Yes, I have

Did you include all relevant data sets for reproducing the issue?

No - Other reason (please specify in the issue body)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions