Re: Using timestamp(tz) in C functions

Поиск
Список
Период
Сортировка
От Keith Fiske
Тема Re: Using timestamp(tz) in C functions
Дата
Msg-id CAG1_KcCmhBN6mBUtFwtxh1NEmB2Ch-0+Om8ukb2C2htQSgD3QQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Using timestamp(tz) in C functions  (Vitaly Burovoy <vitaly.burovoy@gmail.com>)
Ответы Re: Using timestamp(tz) in C functions  (Vitaly Burovoy <vitaly.burovoy@gmail.com>)
Список pgsql-general

On Fri, Jul 29, 2016 at 11:49 AM, Vitaly Burovoy <vitaly.burovoy@gmail.com> wrote:
On 7/29/16, Keith Fiske <keith@omniti.com> wrote:
> On Fri, Jul 29, 2016 at 12:53 AM, Vitaly Burovoy <vitaly.burovoy@gmail.com>
> wrote:
>
>> On 7/28/16, Keith Fiske <keith@omniti.com> wrote:
>> > Working on trying to get a C version of the maintenance function for my
>> > pg_partman extension working so I can hopefully make it more flexible
>> > and
>> > efficient.
>> >
>> https://gist.github.com/keithf4/81c32bf8b689c74b20c10ad8c91d45a3#file-pg_partman_bgw-c-L532
>> >
>> > There's what I've got working so far and links directly to the area
>> > where
>> > I'm having a problem. I found the DatumGetTimeTzADTP() function and the
>> > TimeTzADT data type looking through the source and that seems to be exactly
>> > what I'm looking for. However, when I get to the point of trying to simply
>> > use the time value in that variable (line 544), Postgres segfaults. So far
>> > I've just been trying to print the value out to the log to ensure I'm
>> > pulling it out correctly. The "time" value of the struct appears to be
>> > an
>> > int64, so I thought %ld would be the correct, but even using %d or %s
>> > fails.
>> >
>> > Thanks!
>> >
>> > --
>> > Keith Fiske
>> > Database Administrator
>> > OmniTI Computer Consulting, Inc.
>> > http://www.keithf4.com
>> >
>>
>> I think it is not about timestamp(tz), but about usage of SPI.
>> Since DatumGetTimeTzADTP is just a macros implements type conversion
>> (declared at src/include/utils/date.h:60 (or 75)) you get segfault not
>> in it but when the code tries to get value by dereference pointer
>> (last_partition_timestamp->time).
>>
>> Please, answer questions:
>> 1. How many rows SPI_execute returns (value of "ret" variable)?
>> 2. Is last_partition_timestamp != NULL? Where it points to?
>> 3. Try to check SPI_result just after SPI_getbinval. Has it error code?
>
>
> It returns a single row. Here's an example of the results of the two
> queries that are run that lead to providing the timestamp value
>
> keith=# select partition_tablename from
> partman.show_partitions('partman_test.time_taptest_table', 'DESC') limit
> 1;      partition_tablename
> --------------------------------
>  time_taptest_table_p2016_08_02
> (1 row)
>
> keith=# select child_start_time from
> partman.show_partition_info('partman_test.time_taptest_table_p2016_08_02',
> '1 day', 'partman_test.time_taptest_table');
>     child_start_time
> ------------------------
>  2016-08-02 00:00:00-04
> (1 row)
>
> So there is valid data. As you're pointing out, this may just be a
> misunderstanding of how to actually use the Datum retrieval function and C
> in general. Appreciate the assistance.
>
> Keith
>

Please, add next lines (or debug this values via gdb) and post a result:

ret = SPI_execute(buf.data, true, 1);

ereport(NOTICE, (errmsg("query=%s", buf.data)));
ereport(NOTICE, (errmsg("ret=%i -- rows=%ju", ret, SPI_processed)));

last_partition_timestamp =
DatumGetTimeTzADTP(SPI_getbinval(SPI_tuptable->vals[0],
SPI_tuptable->tupdesc, 1, &isnull));

ereport(NOTICE, (errmsg("SPI_result=%d -- ptr=%p", SPI_result,
(void*)last_partition_timestamp )));

/* elog(LOG, "Just seeing if it's time partitioned: %ld",
last_partition_timestamp->time); --prevent segfaulting */


--
Best regards,
Vitaly Burovoy

From the postgresql logs:

2016-07-29 11:59:39 EDT [] [2021]: [10-1] user=,db=,e=00000 LOG:  Just checking that this thing is working. Loop: 0, parent_table: partman_test.time_taptest_table, partition_type: time, partition_interval: 00:15:00, control: col3, premake: 4, datetime_string: %YYYY_MM_DD_HH24MI, undo_in_progress: 0, sub_partition_set_full: 0, epoch: 0, infinite_time_partitions: 0
2016-07-29 11:59:39 EDT [] [2021]: [11-1] user=,db=,e=00000 NOTICE:  query=SELECT child_start_time FROM partman.show_partition_info('partman_test.time_taptest_table_p2016_07_29_1245', '00:15:00', 'partman_test.time_taptest_table')
2016-07-29 11:59:39 EDT [] [2021]: [12-1] user=,db=,e=00000 NOTICE:  ret=5 -- rows=1
2016-07-29 11:59:39 EDT [] [2021]: [13-1] user=,db=,e=00000 NOTICE:  SPI_result=0 -- ptr=0x1dbc7bd713b00
2016-07-29 11:59:41 EDT [] [2012]: [10-1] user=,db=,e=00000 LOG:  worker process: pg_partman dynamic background worker (dbname=keith) (PID 2021) was terminated by signal 11: Segmentation fault
 
FYI, Also got these notices when compiling:

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fpic -I. -I./ -I/opt/pgsql953/include/server -I/opt/pgsql953/include/internal -D_GNU_SOURCE   -c -o src/pg_partman_bgw.o src/pg_partman_bgw.c -MMD -MP -MF .deps/pg_partman_bgw.Po
In file included from /opt/pgsql953/include/server/postgres.h:48:0,
                 from src/pg_partman_bgw.c:10:
src/pg_partman_bgw.c: In function ‘pg_partman_run_maintenance_c’:
src/pg_partman_bgw.c:623:41: warning: format ‘%ju’ expects argument of type ‘uintmax_t’, but argument 3 has type ‘uint32 {aka unsigned int}’ [-Wformat=]
                 ereport(NOTICE, (errmsg("ret=%i -- rows=%ju", ret, SPI_processed)));
                                         ^
/opt/pgsql953/include/server/utils/elog.h:117:14: note: in definition of macro ‘ereport_domain’
    errfinish rest; \
              ^
src/pg_partman_bgw.c:623:17: note: in expansion of macro ‘ereport’
                 ereport(NOTICE, (errmsg("ret=%i -- rows=%ju", ret, SPI_processed)));
                 ^

В списке pgsql-general по дате отправления:

Предыдущее
От: rob stone
Дата:
Сообщение: 9.6beta3
Следующее
От: Adrian Klaver
Дата:
Сообщение: Re: 9.6beta3