Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproduction commands for leads to segfault or assertion failure, likely invalid memory access #179

Closed
2 tasks done
dentiny opened this issue Dec 16, 2024 · 3 comments
Closed
2 tasks done

Comments

@dentiny
Copy link
Contributor

dentiny commented Dec 16, 2024

What happens?

I'm checking on issue #176.

With reproduce command (see below), duckdb either segfaults or assertion failure.
I have tried to build and execute for different platforms.

On ubuntu 22.04, it fails a duckdb internal assertion.

[~/duckpgq-extension/duckdb] ((HEAD detached at 0c82f0ed58)) 
ubuntu@hjiang-devbox-pg$ uname -a
Linux hjiang-devbox-pg 6.2.0-1018-aws #18~22.04.1-Ubuntu SMP Wed Jan 10 22:54:16 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

[~/duckpgq-extension/duckdb] ((HEAD detached at 0c82f0ed58)) 
ubuntu@hjiang-devbox-pg$ lscpu
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         46 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  32
  On-line CPU(s) list:   0-31
Vendor ID:               GenuineIntel
  Model name:            Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz

Error message:

D CREATE PROPERTY GRAPH SocialNetwork  VERTEX TABLES (    person,     city  )  EDGE TABLES (    follows    SOURCE KEY (p1id) REFERENCES person (id)                  DESTINATION KEY (p2id) REFERENCES person (id),    livesin    SOURCE KEY (personid) REFERENCES person (id)                DESTINATION KEY (cityid) REFERENCES city (id));
INTERNAL Error: Assertion triggered in file "/home/ubuntu/duckpgq-extension/duckdb/src/include/duckdb/common/helper.hpp" on line 256: reinterpret_cast<const T *>(source) == dynamic_cast<const T *>(source)
This error signals an assertion failure within DuckDB. This usually occurs due to unexpected conditions or errors in the program's logic.
For more information, see https://duckdb.org/docs/dev/internal_errors

With gdb attach breakpoint, the stacktrace looks like, which doesn't make sense to me, since it's completely duckdb internals.

(gdb) bt
#0  duckdb::DynamicCastCheck<duckdb::CreateViewInfo, duckdb::ParseInfo> (
    source=0x61400009ea40)
    at /home/ubuntu/duckpgq-extension/duckdb/src/include/duckdb/common/helper.hpp:261
#1  0x000055556867029c in duckdb::ParseInfo::Cast<duckdb::CreateViewInfo> (
    this=0x61400009ea40)
    at /home/ubuntu/duckpgq-extension/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp:49
#2  0x000055556b9bbefb in duckdb::Binder::Bind (this=0x61900001c280, stmt=...)
    at /home/ubuntu/duckpgq-extension/duckdb/src/planner/binder/statement/bind_create.cpp:635
#3  0x000055556bc702a7 in duckdb::Binder::Bind (this=0x61900001c280, statement=...)
    at /home/ubuntu/duckpgq-extension/duckdb/src/planner/binder.cpp:161
#4  0x000055556bc9de10 in duckdb::Planner::CreatePlan (this=0x7fffffffb190, statement=...)
    at /home/ubuntu/duckpgq-extension/duckdb/src/planner/planner.cpp:43
#5  0x000055556bca1137 in duckdb::Planner::CreatePlan (this=0x7fffffffb190, statement=...)
--Type <RET> for more, q to quit, c to continue without paging--c
    at /home/ubuntu/duckpgq-extension/duckdb/src/planner/planner.cpp:142
#6  0x000055556a104fbd in duckdb::ClientContext::CreatePreparedStatementInternal (this=0x616000052290, lock=..., query="CREATE PROPERTY GRAPH SocialNetwork\n  VERTEX TABLES (\n    person, \n    city\n  )\n  EDGE TABLES (\n    follows    SOURCE KEY (p1id) REFERENCES person (id)\n", ' ' <repeats 18 times>, "DESTINATION KEY (p2id) REFEREN"..., statement=..., values=...) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:338
#7  0x000055556a107449 in duckdb::ClientContext::CreatePreparedStatement (this=0x616000052290, lock=..., query="CREATE PROPERTY GRAPH SocialNetwork\n  VERTEX TABLES (\n    person, \n    city\n  )\n  EDGE TABLES (\n    follows    SOURCE KEY (p1id) REFERENCES person (id)\n", ' ' <repeats 18 times>, "DESTINATION KEY (p2id) REFEREN"..., statement=..., values=..., mode=duckdb::PreparedStatementMode::PREPARE_ONLY) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:424
#8  0x000055556a1106ab in operator() (__closure=0x60400009dc10) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:659
#9  0x000055556a3cb16a in std::__invoke_impl<void, duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement>)::<lambda()>&>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/11/bits/invoke.h:61
#10 0x000055556a1d6a24 in std::__invoke_r<void, duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement>)::<lambda()>&>(struct {...} &) (__fn=...) at /usr/include/c++/11/bits/invoke.h:154
#11 0x000055556a1d1fb9 in std::_Function_handler<void(), duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement>)::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/11/bits/std_function.h:290
#12 0x0000555569f674f2 in std::function<void ()>::operator()() const (this=0x7fffffffbcf0) at /usr/include/c++/11/bits/std_function.h:590
#13 0x000055556a11decf in duckdb::ClientContext::RunFunctionInTransactionInternal(duckdb::ClientContextLock&, std::function<void ()> const&, bool) (this=0x616000052290, lock=..., fun=..., requires_valid_transaction=false) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:1082
#14 0x000055556a110d23 in duckdb::ClientContext::PrepareInternal (this=0x616000052290, lock=..., statement=...) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:658
#15 0x000055556a111530 in duckdb::ClientContext::Prepare (this=0x616000052290, statement=...) at /home/ubuntu/duckpgq-extension/duckdb/src/main/client_context.cpp:671
#16 0x000055556a140bc7 in duckdb::Connection::Prepare (this=0x60300006f730, statement=...) at /home/ubuntu/duckpgq-extension/duckdb/src/main/connection.cpp:152
#17 0x000055556830ac14 in duckdb_shell_sqlite3_prepare_v2 (db=0x60f000000400, zSql=0x61400009e840 "CREATE PROPERTY GRAPH SocialNetwork\n  VERTEX TABLES (\n    person, \n    city\n  )\n  EDGE TABLES (\n    follows    SOURCE KEY (p1id) REFERENCES person (id)\n", ' ' <repeats 18 times>, "DESTINATION KEY (p2id) REFEREN"..., nByte=-1, ppStmt=0x7fffffffc540, pzTail=0x7fffffffc560) at /home/ubuntu/duckpgq-extension/duckdb/tools/sqlite3_api_wrapper/sqlite3_api_wrapper.cpp:204
#18 0x0000555568265865 in shell_exec (pArg=0x7fffffffc7e0, zSql=0x61400009e840 "CREATE PROPERTY GRAPH SocialNetwork\n  VERTEX TABLES (\n    person, \n    city\n  )\n  EDGE TABLES (\n    follows    SOURCE KEY (p1id) REFERENCES person (id)\n", ' ' <repeats 18 times>, "DESTINATION KEY (p2id) REFEREN"..., pzErrMsg=0x7fffffffc640) at /home/ubuntu/duckpgq-extension/duckdb/tools/shell/shell.c:12993
#19 0x0000555568298b4d in runOneSqlLine (p=0x7fffffffc7e0, zSql=0x61400009e840 "CREATE PROPERTY GRAPH SocialNetwork\n  VERTEX TABLES (\n    person, \n    city\n  )\n  EDGE TABLES (\n    follows    SOURCE KEY (p1id) REFERENCES person (id)\n", ' ' <repeats 18 times>, "DESTINATION KEY (p2id) REFEREN"..., in=0x0, startline=8) at /home/ubuntu/duckpgq-extension/duckdb/tools/shell/shell.c:19273
#20 0x0000555568299ffb in process_input (p=0x7fffffffc7e0) at /home/ubuntu/duckpgq-extension/duckdb/tools/shell/shell.c:19384
#21 0x000055556829ef1c in main (argc=1, argv=0x7fffffffdc58) at /home/ubuntu/duckpgq-extension/duckdb/tools/shell/shell.c:20206

I also tried on macos, it shows heap overflow.

hjiang@hjiang-H4C6VDYY32 ~ % uname -a
Darwin hjiang-H4C6VDYY32.local 23.6.0 Darwin Kernel Version 23.6.0: Wed Jul 31 20:48:04 PDT 2024; root:xnu-10063.141.1.700.5~1/RELEASE_ARM64_T6030 arm64

hjiang@hjiang-H4C6VDYY32 ~ % sysctl -n machdep.cpu.brand_string
Apple M3 Pro

The ASAN output is

=================================================================
==92816==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6130000b3ea8 at pc 0x000103bc0f68 bp 0x00016d0b58a0 sp 0x00016d0b5898
READ of size 8 at 0x6130000b3ea8 thread T0
    #0 0x103bc0f64 in std::__1::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>>::get[abi:ne180100]() const unique_ptr.h:247
    #1 0x103af4f74 in duckdb::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>, true>::operator->() const unique_ptr.hpp:40
    #2 0x103d93894 in duckdb::Binder::BindCreateViewInfo(duckdb::CreateViewInfo&) bind_create.cpp:163
    #3 0x103da5cb8 in duckdb::Binder::Bind(duckdb::CreateStatement&) bind_create.cpp:638
    #4 0x1043d066c in duckdb::Binder::Bind(duckdb::SQLStatement&) binder.cpp:161
    #5 0x10442a2a0 in duckdb::Planner::CreatePlan(duckdb::SQLStatement&) planner.cpp:43
    #6 0x10442ffc0 in duckdb::Planner::CreatePlan(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>) planner.cpp:142
    #7 0x10d04af40 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:338
    #8 0x10d0505fc 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:424
    #9 0x10d3a1d68 in duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0::operator()() const client_context.cpp:659
    #10 0x10d3a1970 in decltype(std::declval<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0&>()()) std::__1::__invoke[abi:ne180100]<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0&>(duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0&) invoke.h:344
    #11 0x10d3a17f4 in void std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:ne180100]<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0&>(duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0&) invoke.h:419
    #12 0x10d3a178c in std::__1::__function::__alloc_func<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0, std::__1::allocator<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0>, void ()>::operator()[abi:ne180100]() function.h:169
    #13 0x10d39b2f4 in std::__1::__function::__func<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0, std::__1::allocator<duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>)::$_0>, void ()>::operator()() function.h:311
    #14 0x103843c08 in std::__1::__function::__value_func<void ()>::operator()[abi:ne180100]() const function.h:428
    #15 0x1035d9960 in std::__1::function<void ()>::operator()() const function.h:981
    #16 0x10d05fef8 in duckdb::ClientContext::RunFunctionInTransactionInternal(duckdb::ClientContextLock&, std::__1::function<void ()> const&, bool) client_context.cpp:1082
    #17 0x10d061108 in duckdb::ClientContext::PrepareInternal(duckdb::ClientContextLock&, duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>) client_context.cpp:658
    #18 0x10d062050 in duckdb::ClientContext::Prepare(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>) client_context.cpp:671
    #19 0x10d0a4c8c in duckdb::Connection::Prepare(duckdb::unique_ptr<duckdb::SQLStatement, std::__1::default_delete<duckdb::SQLStatement>, true>) connection.cpp:152
    #20 0x102f45950 in duckdb_shell_sqlite3_prepare_v2 sqlite3_api_wrapper.cpp:204
    #21 0x102da961c in shell_exec shell.c:12993
    #22 0x102e697f4 in runOneSqlLine shell.c:19273
    #23 0x102daf400 in process_input shell.c:19384
    #24 0x102d654e4 in main shell.c:20206
    #25 0x181317150 in start+0x9a8 (dyld:arm64e+0xfffffffffff4d150)

0x6130000b3ea8 is located 8 bytes after 352-byte region [0x6130000b3d40,0x6130000b3ea0)
allocated by thread T0 here:
    #0 0x12048fe94 in _Znwm+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x63e94)
    #1 0x1047bb184 in duckdb::TemplatedUniqueIf<duckdb::CreatePropertyGraphInfo, true>::templated_unique_single_t duckdb::make_uniq<duckdb::CreatePropertyGraphInfo>() helper.hpp:65
    #2 0x104a81dd0 in duckdb::Transformer::TransformCreatePropertyGraph(duckdb_libpgquery::PGCreatePropertyGraphStmt&) transform_create_property_graph.cpp:143
    #3 0x104bf7ffc in duckdb::Transformer::TransformStatementInternal(duckdb_libpgquery::PGNode&) transformer.cpp:219
    #4 0x104bf4028 in duckdb::Transformer::TransformStatement(duckdb_libpgquery::PGNode&) transformer.cpp:59
    #5 0x104bf54f4 in duckdb::Transformer::TransformStatementInternal(duckdb_libpgquery::PGNode&) transformer.cpp:139
    #6 0x104bf4028 in duckdb::Transformer::TransformStatement(duckdb_libpgquery::PGNode&) transformer.cpp:59
    #7 0x104baddd8 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 0x104baa21c in duckdb::Parser::ParseQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&) parser.cpp:219
    #9 0x102f44c7c in duckdb_shell_sqlite3_prepare_v2 sqlite3_api_wrapper.cpp:176
    #10 0x102da961c in shell_exec shell.c:12993
    #11 0x102e697f4 in runOneSqlLine shell.c:19273
    #12 0x102daf400 in process_input shell.c:19384
    #13 0x102d654e4 in main shell.c:20206
    #14 0x181317150 in start+0x9a8 (dyld:arm64e+0xfffffffffff4d150)

SUMMARY: AddressSanitizer: heap-buffer-overflow unique_ptr.h:247 in std::__1::unique_ptr<duckdb::SelectStatement, std::__1::default_delete<duckdb::SelectStatement>>::get[abi:ne180100]() const
Shadow bytes around the buggy address:
  0x6130000b3c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000b3c80: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
  0x6130000b3d00: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x6130000b3d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000b3e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x6130000b3e80: 00 00 00 00 fa[fa]fa fa fa fa fa fa fa fa fa fa
  0x6130000b3f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000b3f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x6130000b4000: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
  0x6130000b4080: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x6130000b4100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==92816==ABORTING
zsh: abort      ./build/debug/duckdb

I build duckdb-pgq myself from scratch, with command make debug.

To Reproduce

-- works
CREATE TABLE city (
  id bigint PRIMARY KEY,
  name varchar
);

CREATE TABLE person (
  id bigint PRIMARY KEY,
  name varchar
);
CREATE TABLE livesIn (
  personid bigint,
  cityid bigint
);

CREATE TABLE follows (
  p1id bigint,
  p2id bigint
);

-- crashes
CREATE PROPERTY GRAPH SocialNetwork
  VERTEX TABLES (
	person, 
	city
  )
  EDGE TABLES (
	follows	SOURCE KEY (p1id) REFERENCES person (id)
			  	DESTINATION KEY (p2id) REFERENCES person (id),
	livesin	SOURCE KEY (personid) REFERENCES person (id)
				DESTINATION KEY (cityid) REFERENCES city (id)
);

OS:

aarch64 for mac, x84_64 for ubuntu

duckdb-pgq commit:

fb38a09

DuckDB Version:

0c82f0ed582ed2737216539845028826badb4bda

DuckDB Client:

self built

Full Name:

Hao

Affiliation:

N/A

How did you load the extension?

Built from source

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

Not applicable - the reproduction does not require a data set

Did you include all code required to reproduce the issue?

  • Yes, I have

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

  • Yes, I have
@dentiny dentiny changed the title Reproduction commands for leads to segfault or assertion failure Reproduction commands for leads to segfault or assertion failure, likely invalid memory access Dec 16, 2024
@dentiny
Copy link
Contributor Author

dentiny commented Dec 16, 2024

Some quick investigation, what caught my eye:

@Dtenwolde
Copy link
Contributor

Hi @dentiny, this is my bad and I should have told you. Whenever you build the extension from source, any queries that contain PGQ syntax (e.g. CREATE PROPERTY GRAPH or MATCH) need to start with a -. This ensures the DuckDB parser fails and the duckpgq parser is triggered from the parser extension.
I did document this in the Building DuckPGQ:
https://www.notion.so/duckpgq/Building-DuckPGQ-619783a5af604efbb7c93f09811d996f

The reason is somewhat complex but I'll try to explain it anyway.

We build the extension on a fork of DuckDB, this is already different from most other extensions, which build on the main DuckDB. This fork of ours includes changes to the parser and transformer to include the PGQ syntax and be able to transform the result into an Abstract Syntax Tree (AST). Therefore, our parser + transformer is a superset of the DuckDB parser and PGQ.
However, to trigger the correct code path for this when built from source, we need to ensure the parser extension is triggered by deliberately adding a parser error in the query. This is the - at the start of every PGQ query. Therefore the initial parse attempt by DuckDB fails and triggers the parser extension.
This is the line where we look at trim the - and run the parser again from our parser:

parser.ParseQuery((query[0] == '-') ? query.substr(1, query.length())

This is not an issue when users load the extension and there's no need for them to write a - at the start of a PGQ query.

I have also forgotten to use this - during testing and wondered why I all of a sudden got a segmentation fault at a weird place so I should've warned you.

@dentiny
Copy link
Contributor Author

dentiny commented Dec 16, 2024

Thanks for the explanation @Dtenwolde ! Now I understand -- I was actually curious and surprised why we modify duckdb source code.

Ah I should play with the test first, a second look at the test, sqls with property-graph involved does start with -.

statement ok
-CREATE PROPERTY GRAPH pg
VERTEX TABLES (
Student PROPERTIES ( id, name ) LABEL Person,
School LABEL SCHOOL
)
EDGE TABLES (
know SOURCE KEY ( src ) REFERENCES Student ( id )
DESTINATION KEY ( dst ) REFERENCES Student ( id )
LABEL Knows,
studyAt SOURCE KEY ( personId ) REFERENCES Student ( id )
DESTINATION KEY ( SchoolId ) REFERENCES School ( id )
LABEL StudyAt
);

I open a PR to add some documentation on "build from scratch part", let me know if you think it's ok :)

@dentiny dentiny closed this as completed Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants