Thread: Re: determine what column(s) form the primary key, in C extention
I'm emailing it to the 'general' list. (1) This: int i = -1; while ((i = bms_next_member(pkattnos , i)) >= 0) { /* do stuff with i */ /* you'll need to use i - FirstLowInvalidHeapAttributeNumber to get the pg_attribute.attnum */ elog(INFO, "bms_next_member i: %d", i); } prints 10 and then 9 Then: 10 - FirstLowInvalidHeapAttributeNumber (-8) ==> 2 9 - FirstLowInvalidHeapAttributeNumber (-8) ==> 1 These are indexes of the columns, right? Do they start from 1, not from 0? (2) I'll use this C code as an example to build an extention in Rust. The Postgresql bindings for Rust I have don't contain a definition of `FirstLowInvalidHeapAttributeNumber` for some reason. I can define it since it's simply single digit constant. However what does in some source files it's defined as (-7) and in some as (-8)? Which should I use? El 28/07/2020 a las 03:20, David Rowley escribió: > Hi Alex, > > On Tue, 28 Jul 2020 at 05:47, alex maslakov <alex@serendipia.email> wrote: >> I was suggested to use `get_primary_key_attnos` from >> `src/include/catalog/pg_constraint.h` >> >> extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk) >> >> >> It returns *Bitstamp. And it's got "nwords" and "words[]". But those >> return just big numbers, not something that look similar to an index of >> the primary key column. >> >> >> And therefore I haven't had any luck thus far. >> >> How to do it? > You'll need to loop over the return value of that function with > bms_next_member() > > e.g. > pkattnos = get_primary_key_attnos(oid, false); > i = -1; > while ((i = bms_next_member(pkattnos , i)) >= 0) > { > /* do stuff with i */ > /* you'll need to use i - FirstLowInvalidHeapAttributeNumber to get > the pg_attribute.attnum */ > } > > For the future, for questions, you should use the general list. If > the question is very source code related then you might have more luck > in pgsql-hackers. This is not the right list. Please post any > followup questions on one of those lists. > > Note the description for this list, per > https://www.postgresql.org/list/ is "Notification of git commits are > sent to this list. Do not post here!" > > David
On Wed, 29 Jul 2020 at 03:45, alex maslakov <alex@serendipia.email> wrote: > int i = -1; > while ((i = bms_next_member(pkattnos , i)) >= 0) { > /* do stuff with i */ > /* you'll need to use i - FirstLowInvalidHeapAttributeNumber to > get the pg_attribute.attnum */ > > > elog(INFO, "bms_next_member i: %d", i); > } > > prints 10 and then 9 > > Then: > > 10 - FirstLowInvalidHeapAttributeNumber (-8) ==> 2 > > 9 - FirstLowInvalidHeapAttributeNumber (-8) ==> 1 > > These are indexes of the columns, right? > > Do they start from 1, not from 0? User attributes start at 1. Have a look at the pg_attribute system catalogue table. The number you get will be the attnum column from that table. > (2) > > I'll use this C code as an example to build an extention in Rust. The > Postgresql bindings for Rust I have don't contain a definition of > `FirstLowInvalidHeapAttributeNumber` for some reason. I can define it > since it's simply single digit constant. > > However what does in some source files it's defined as (-7) and in some > as (-8)? Which should I use? It did recently change from -8 to -7 when we removed Oid as a system column in pg12. The number will never change on a major version, so you'll always know what it is for versions that have already been released. There's always a chance it'll change from -7 in some future PostgreSQL version though. David
(2)
I'll use this C code as an example to build an extention in Rust. The
Postgresql bindings for Rust I have don't contain a definition of
`FirstLowInvalidHeapAttributeNumber` for some reason. I can define it
since it's simply single digit constant.
Not an answer to your question - but use better bindings! https://github.com/zombodb/pgx
[nix-shell:~/rust/pgx_master]$ grep -R FirstLowInvalidHeapAttributeNumber pgx-pg-sys/
pgx-pg-sys/generated-bindings/pg12_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -7;
pgx-pg-sys/generated-bindings/pg12_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -7;
Which is obviously not quite right still, so I pushed a version with some extra includes. Now you will get:
[nix-shell:~/rust/pgx_master]$ grep -R FirstLowInvalidHeapAttributeNumber ./pgx-pg-sys/
./pgx-pg-sys/generated-bindings/pg10_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -8;
./pgx-pg-sys/generated-bindings/pg12_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -7;
./pgx-pg-sys/generated-bindings/pg11_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -8;
./pgx-pg-sys/generated-bindings/pg10_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -8;
./pgx-pg-sys/generated-bindings/pg12_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -7;
./pgx-pg-sys/generated-bindings/pg11_specific.rs:pub const FirstLowInvalidHeapAttributeNumber: i32 = -8;
You'll need to use the Github version not the crates.io until the next release if you want all the versions.