Code Monkey home page Code Monkey logo

plprofiler's People

Contributors

glynastill avatar hughcapet avatar kotsachin avatar luss avatar rasifr avatar wieck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

plprofiler's Issues

[question] How to verify if profiler is running? How to disable profiling if connection is lost?

Hello,

It is mentioned in the docs:
"As with any database maintenance operations, this should only be done in a connection loss safe environment as losing the connection in the middle of the monitoring would leave those settings behind permanently."

In case profiling was running when connection was lost, can we verify somehow that profiling is active on the database?
How can we disable profiling if connection is lost in the middle of the monitoring?

Sorry for asking duplicate question if this is already mentioned somewhere. I couldn't find this information.

Thank you for the info.

Issue with PLPROFILER

Hi Guys,

Am Configuring PLPROFILER on RHEL8 to support aurora postgres database 11.9.
Am Encountering the below error in every environment configured. If we exclude --output parameter the error doesnt occur.

Googling around doesn't give me much of a solution.

Traceback (most recent call last):
File "/usr/local/bin/plprofiler", line 11, in
load_entry_point('plprofiler==4.1', 'console_scripts', 'plprofiler')()
File "/usr/local/lib/python3.6/site-packages/plprofiler/plprofiler_tool.py", line 75, in main
return run_command(sys.argv[2:])
File "/usr/local/lib/python3.6/site-packages/plprofiler/plprofiler_tool.py", line 844, in run_command
report_data = plp.get_local_report_data(opt_name, opt_top, args)
File "/usr/local/lib/python3.6/site-packages/plprofiler/plprofiler.py", line 403, in get_local_report_data
raise Exception("No profiling data found")
Exception: No profiling data found

References:

https://www.percona.com/blog/2019/02/13/plprofiler-getting-a-handy-tool-for-profiling-your-pl-pgsql-code/
https://dzone.com/articles/plprofiler-getting-a-handy-tool-for-profiling-your-1

Docs issues: Unable to install via pip, oscg.io not working

I'm trying to install this package in my Alpine-based Docker image:

FROM postgres:15-alpine3.18 AS plprofiler

# Install plprofiler
# See https://github.com/bigsql/plprofiler/blob/master/doc/installation.md
RUN apk add python3 py3-pip \
    && pip install --upgrade pip \
    && pip install plprofiler plprofiler-client psycopg2-binary

It looks like there at least one more step is missing to install the extension properly, because when I run CREATE EXTENSION IF NOT EXISTS "plprofiler";, I get this error back:

[0A000] ERROR: extension "plprofiler" is not available Detail: Could not open extension control file "/usr/local/share/postgresql/extension/plprofiler.control": No such file or directory. Hint: The extension must first be installed on the system where PostgreSQL is running.

Can somebody please shed some light on this?

Also, the docs talk about oscg.io which isn't working.

Calling pl_profiler_get_stack() with bogus arguments crashes database

Issue:
Calling pg_profiler_get_stack() with bogus arguments crashes server.

SQL Output:

t=> select version();
                                                   version
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 13.1 on aarch64-unknown-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6), 64-bit
(1 row)

t=> \dx *profiler
                             List of installed extensions
    Name    | Version | Schema |                     Description
------------+---------+--------+------------------------------------------------------
 plprofiler | 4.1     | public | server-side support for profiling PL/pgSQL functions
(1 row)

t=> select pl_profiler_get_stack(NULL::_oid);
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.

Error Log:

2021-01-06 02:32:48 UTC::@:[4393]:LOG:  server process (PID 17139) was terminated by signal 11: Segmentation fault
2021-01-06 02:32:48 UTC::@:[4393]:DETAIL:  Failed process was running: select pl_profiler_get_stack(NULL::_oid);
2021-01-06 02:32:48 UTC::@:[4393]:LOG:  terminating any other active server processes

install profiler gives an error

Hi,

postgres@student:~/plprofiler$ pwd
/var/lib/postgresql/plprofiler
postgres@student:~/plprofiler$
postgres@student:~/plprofiler$ sudo USE_PGXS=1 make install
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer -fPIC -I. -I./ -I/usr/include/postgresql/12/server -I/usr/include/postgresql/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2  -I/usr/include/mit-krb5  -c -o plprofiler.o plprofiler.c
plprofiler.c:20:10: fatal error: postgres.h: No such file or directory
   20 | #include "postgres.h"
      |          ^~~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: plprofiler.o] Error 1
postgres@student:~/plprofiler$

If install from contrib directory I got another error:

postgres@student:/usr/share/postgresql/12/contrib/plprofiler$ make install
Makefile:27: /contrib/contrib-global.mk: No such file or directory
make: *** No rule to make target '/contrib/contrib-global.mk'.  Stop.
postgres@student:/usr/share/postgresql/12/contrib/plprofiler$

I cant find contrib-global.mk - so maybe its wrong contrib??
but in any case, this does not explain the error in the first case when the installation does not come from the contrib.

Postgres version :

postgres=# select version();
                                                             version                                                              
----------------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 12.5 (Ubuntu 12.5-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, 64-bit
(1 row)

postgres=#

plprofiler always returns "No profiling data found" even when using the command option

I have tried the example given in the repo and plprofiler returns "No profiling data found"

Environment:
I have postgres 13
I build plprofiler from source using PGXS=1 option
I have added plprofiler to shared_preload_libraries

Steps I have followed:

> pwd
> /work/plprofiler/examples

> psql
>> postgres=# CREATE DATABASE pgbench_plprofiler;
>> postgres=# CREATE DATABASE
>> postgres=# \q

> ./predb.sh
dropping old tables...
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
1000000 of 1000000 tuples (100%) done (elapsed 0.67 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 1.17 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 0.70 s, vacuum 0.25 s, primary keys 0.21 s).                 CREATE FUNCTION 
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
DROP EXTENSION IF EXISTS plprofiler;
NOTICE:  extension "plprofiler" does not exist, skipping
DROP EXTENSION
CREATE EXTENSION plprofiler;
CREATE EXTENSION
DROP SEQUENCE IF EXISTS pgbench_category_seq;
NOTICE:  sequence "pgbench_category_seq" does not exist, skipping
DROP SEQUENCE
CREATE SEQUENCE pgbench_category_seq;
CREATE SEQUENCE
DROP TABLE IF EXISTS pgbench_accounts_new;
NOTICE:  table "pgbench_accounts_new" does not exist, skipping
DROP TABLE
CREATE TABLE pgbench_accounts_new (
    category    integer default (nextval('pgbench_category_seq') / 20),
        aid                     integer NOT NULL,
        bid                     integer,
        abalance        integer,
        filler          character(1000)
)
WITH (FILLFACTOR = 90);
CREATE TABLE
INSERT INTO pgbench_accounts_new
                (aid, bid, abalance, filler)
        SELECT aid, bid, abalance,
                        '11111111111111111111111111111111111111111111111111' ||
                        '11111111111111111111111111111111111111111111111111' ||
                        '22222222222222222222222222222222222222222222222222' ||
                        '22222222222222222222222222222222222222222222222222' ||
                        '33333333333333333333333333333333333333333333333333' ||
                        '33333333333333333333333333333333333333333333333333' ||
                        '44444444444444444444444444444444444444444444444444' ||
                        '44444444444444444444444444444444444444444444444444' ||
                        '55555555555555555555555555555555555555555555555555' ||
                        '55555555555555555555555555555555555555555555555555'
        FROM pgbench_accounts;
INSERT 0 1000000
DROP TABLE pgbench_accounts;
DROP TABLE
ALTER TABLE pgbench_accounts_new RENAME TO pgbench_accounts;
ALTER TABLE
ALTER TABLE pgbench_accounts ADD CONSTRAINT pgbench_accounts_pkey
        PRIMARY KEY (category, aid);
ALTER TABLE
VACUUM FULL ANALYZE pgbench_accounts;
VACUUM

> plprofiler run --command "SELECT tpcb(1, 2, 3, -42)" -d pgbench_plprofiler --output tpcb-test1.html
SELECT tpcb(1, 2, 3, -42)
-- row1:
  tpcb: -42
----
(1 rows)
SELECT 1 (0.023 seconds)

Traceback (most recent call last):
  File "/home/doc/.pyenv/versions/3.11.4/bin/plprofiler", line 33, in <module>
    sys.exit(load_entry_point('plprofiler-client==4.2', 'console_scripts', 'plprofiler')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/doc/.pyenv/versions/3.11.4/lib/python3.11/site-packages/plprofiler_client-4.2-py3.11.egg/plprofiler/plprofiler_tool.py", line 75, in main
    return run_command(sys.argv[2:])
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/doc/.pyenv/versions/3.11.4/lib/python3.11/site-packages/plprofiler_client-4.2-py3.11.egg/plprofiler/plprofiler_tool.py", line 844, in run_command
    report_data = plp.get_local_report_data(opt_name, opt_top, args)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/doc/.pyenv/versions/3.11.4/lib/python3.11/site-packages/plprofiler_client-4.2-py3.11.egg/plprofiler/plprofiler.py", line 403, in get_local_report_data
    raise Exception("No profiling data found")
Exception: No profiling data found

I am running Postgres in WSL. Could that be the reason?. i didnt have any errors while building or loading plprofiler.

AttributeError: 'NoneType' object has no attribute 'replace' - when generating plprofiler report

Hello,

I am getting error AttributeError: 'NoneType' object has no attribute 'replace' when generating plprofiler report.

Environment:
PostgreSQL 11.16 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
CentOS Linux release 7.9.2009 (Core)

To reproduce:

  1. Start monitor for global profiling (even tried to profile exact backend pid):

$ plprofiler monitor --interval=10 --duration=60 -d pgworkload

  1. Run sample queries/calls in separate session.

  2. Once data is captured run report.

$ plprofiler report --from-shared --title=TesProfileProc --output=TesProfileProc.html -d pgworkload

Traceback (most recent call last):
  File "/usr/local/bin/plprofiler", line 33, in <module>
    sys.exit(load_entry_point('plprofiler==4.1', 'console_scripts', 'plprofiler')())
  File "/usr/local/lib/python3.6/site-packages/plprofiler-4.1-py3.6.egg/plprofiler/plprofiler_tool.py", line 66, in main
    return report_command(sys.argv[2:])
  File "/usr/local/lib/python3.6/site-packages/plprofiler-4.1-py3.6.egg/plprofiler/plprofiler_tool.py", line 512, in report_command
    plp.report(report_data, output_fd)
  File "/usr/local/lib/python3.6/site-packages/plprofiler-4.1-py3.6.egg/plprofiler/plprofiler.py", line 1012, in report
    report.generate(report_data, output_fd)
  File "/usr/local/lib/python3.6/site-packages/plprofiler-4.1-py3.6.egg/plprofiler/plprofiler_report.py", line 49, in generate
    self.generate_function_output(config, func_def)
  File "/usr/local/lib/python3.6/site-packages/plprofiler-4.1-py3.6.egg/plprofiler/plprofiler_report.py", line 87, in generate_function_output
    funcresult = func_def['funcresult'].replace(' ', '&nbsp;')))
AttributeError: 'NoneType' object has no attribute 'replace'

plprofiler on windows

where does plprofiler want the format html file that pops up to be saved? i've tried serveral places with no luck. sample commands
c:\plprofiler\plprofiler-master\examples> plprofiler run --host=pg-xxxxx.rds.amazonaws.com --user=myuser --dbname=postgres --file tpcb_queries.sql --output tpcb-test1.html
select tpcb(100,1,1,10);
-- row1:
tpcb: 10

(1 rows)
SELECT 1 (0.247 seconds)

select tpcb(200,1,1,10);
-- row1:
tpcb: 10

(1 rows)
SELECT 1 (0.099 seconds)
Where does the tmpfwxb3g2f.tmp.conf need to be saved when it pops up after the queries run?

Traceback (most recent call last):
File "C:\Python37_64\Scripts\plprofiler-script.py", line 11, in
load_entry_point('plprofiler==4.1', 'console_scripts', 'plprofiler')()
File "C:\Python37_64\lib\site-packages\plprofiler-4.1-py3.7.egg\plprofiler\plprofiler_tool.py", line 75, in main
return run_command(sys.argv[2:])
File "C:\Python37_64\lib\site-packages\plprofiler-4.1-py3.7.egg\plprofiler\plprofiler_tool.py", line 846, in run_command
plp.report(report_data, output_fd)
File "C:\Python37_64\lib\site-packages\plprofiler-4.1-py3.7.egg\plprofiler\plprofiler.py", line 1012, in report
report.generate(report_data, output_fd)
File "C:\Python37_64\lib\site-packages\plprofiler-4.1-py3.7.egg\plprofiler\plprofiler_report.py", line 30, in generate
self.out(self.generate_flamegraph(config, report_data['flamedata']))
File "C:\Python37_64\lib\site-packages\plprofiler-4.1-py3.7.egg\plprofiler\plprofiler_report.py", line 131, in generate_flamegraph
stderr = subprocess.PIPE);
File "C:\Python37_64\lib\subprocess.py", line 800, in init
restore_signals, start_new_session)
File "C:\Python37_64\lib\subprocess.py", line 1207, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

AttributeError: module 'cgi' has no attribute 'escape'

Hi,

I am hitting AttributeError: module 'cgi' has no attribute 'escape' while running sample test report with plprofiler.

Environment: Ubuntu 20.04 (Focal), PostgreSQL-12.6, plprofiler code from git master branch.

  1. Prepare sample database
$ ./prepdb.sh 
dropping old tables...
creating tables...
generating data...
100000 of 1000000 tuples (10%) done (elapsed 0.09 s, remaining 0.82 s)
200000 of 1000000 tuples (20%) done (elapsed 0.19 s, remaining 0.78 s)
300000 of 1000000 tuples (30%) done (elapsed 0.30 s, remaining 0.69 s)
400000 of 1000000 tuples (40%) done (elapsed 0.41 s, remaining 0.62 s)
500000 of 1000000 tuples (50%) done (elapsed 0.53 s, remaining 0.53 s)
600000 of 1000000 tuples (60%) done (elapsed 0.64 s, remaining 0.42 s)
700000 of 1000000 tuples (70%) done (elapsed 0.75 s, remaining 0.32 s)
800000 of 1000000 tuples (80%) done (elapsed 0.87 s, remaining 0.22 s)
900000 of 1000000 tuples (90%) done (elapsed 1.04 s, remaining 0.12 s)
1000000 of 1000000 tuples (100%) done (elapsed 1.16 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
DROP EXTENSION IF EXISTS plprofiler;
DROP EXTENSION
CREATE EXTENSION plprofiler;
CREATE EXTENSION
DROP SEQUENCE IF EXISTS pgbench_category_seq;
DROP SEQUENCE
CREATE SEQUENCE pgbench_category_seq;
CREATE SEQUENCE
DROP TABLE IF EXISTS pgbench_accounts_new;
NOTICE:  table "pgbench_accounts_new" does not exist, skipping
DROP TABLE
CREATE TABLE pgbench_accounts_new (
    category	integer default (nextval('pgbench_category_seq') / 20),
	aid			integer NOT NULL,
	bid			integer,
	abalance	integer,
	filler		character(1000)
)
WITH (FILLFACTOR = 90);
CREATE TABLE
INSERT INTO pgbench_accounts_new
		(aid, bid, abalance, filler)
	SELECT aid, bid, abalance,
			'11111111111111111111111111111111111111111111111111' ||
			'11111111111111111111111111111111111111111111111111' ||
			'22222222222222222222222222222222222222222222222222' ||
			'22222222222222222222222222222222222222222222222222' ||
			'33333333333333333333333333333333333333333333333333' ||
			'33333333333333333333333333333333333333333333333333' ||
			'44444444444444444444444444444444444444444444444444' ||
			'44444444444444444444444444444444444444444444444444' ||
			'55555555555555555555555555555555555555555555555555' ||
			'55555555555555555555555555555555555555555555555555'
	FROM pgbench_accounts;
INSERT 0 1000000
DROP TABLE pgbench_accounts;
DROP TABLE
ALTER TABLE pgbench_accounts_new RENAME TO pgbench_accounts;
ALTER TABLE
ALTER TABLE pgbench_accounts ADD CONSTRAINT pgbench_accounts_pkey
	PRIMARY KEY (category, aid);
ALTER TABLE
VACUUM FULL ANALYZE pgbench_accounts;
VACUUM
  1. Run sample plprofiler report
$ plprofiler run --command "SELECT tpcb(1, 2, 3, -42)" -U postgres -d pgbench_plprofiler --output ~/tpcb-test1.html
SELECT tpcb(1, 2, 3, -42)
-- row1:
  tpcb: -42

(1 rows)
SELECT 1 (0.030 seconds)

Traceback (most recent call last):
  File "/usr/local/bin/plprofiler", line 11, in <module>
    load_entry_point('plprofiler==4.1', 'console_scripts', 'plprofiler')()
  File "/usr/local/lib/python3.8/dist-packages/plprofiler-4.1-py3.8.egg/plprofiler/plprofiler_tool.py", line 75, in main
    return run_command(sys.argv[2:])
  File "/usr/local/lib/python3.8/dist-packages/plprofiler-4.1-py3.8.egg/plprofiler/plprofiler_tool.py", line 846, in run_command
    plp.report(report_data, output_fd)
  File "/usr/local/lib/python3.8/dist-packages/plprofiler-4.1-py3.8.egg/plprofiler/plprofiler.py", line 1012, in report
    report.generate(report_data, output_fd)
  File "/usr/local/lib/python3.8/dist-packages/plprofiler-4.1-py3.8.egg/plprofiler/plprofiler_report.py", line 21, in generate
    self.out("  <title>%s</title>" %(cgi.escape(config['title']), ))
AttributeError: module 'cgi' has no attribute 'escape'

Will submit the pull request to fix this shortly.

Regards,
Sachin

oddities with linestats output

Hi there,

I've noticed a couple of odd things about the results of pl_profiler_linestats_shared() which the example below will hopefully illustrate:

psql -h /tmp/tmp.7v2f8Z5orw test
psql (13.2)
Type "help" for help.

test=# select pl_profiler_reset_shared();
 pl_profiler_reset_shared
--------------------------

(1 row)

test=# create or replace function test_function(input int)
returns int
language plpgsql
as $$
begin
    if input % 2 = 0
    then
       raise debug 'test_function called at %', current_timestamp;
    else
        perform pg_sleep(0.001);
    end if;
    return input;
end;
$$;
CREATE FUNCTION
test=# select sum(test_function(x)) from generate_series(1, 10000) as x;
   sum
----------
 50005000
(1 row)

test=# select * from pl_profiler_linestats_shared();
 func_oid | line_number | exec_count | total_time | longest_time
----------+-------------+------------+------------+--------------
    16477 |           0 |      10000 |   10244529 |         2283
    16477 |           1 |          0 |          0 |            0
    16477 |           2 |      10000 |   10241141 |         2281
    16477 |           3 |      10000 |   10238814 |         2281
    16477 |           4 |          0 |          0 |            0
    16477 |           5 |       5000 |       8576 |           52
    16477 |           6 |          0 |          0 |            0
    16477 |           7 |       5000 |   10226986 |         2281
    16477 |           8 |          0 |          0 |            0
    16477 |           9 |      10000 |         20 |            9
    16477 |          10 |          0 |          0 |            0
    16477 |          11 |          0 |          0 |            0
    16477 |          12 |          0 |          0 |            0
    16477 |          13 |       5000 |       6976 |           70
(14 rows)

If we line up the function source code with the results (and interpret line zero as "function totals") we get something like:

line  exec_count  total_time  longest_time  source
 0         10000    10244529          2283  (totals)
 1             0           0             0 
 2         10000    10241141          2281  begin
 3         10000    10238814          2281    if input % 2 = 0
 4             0           0             0    then
 5          5000        8576            52      raise debug 'test_function called at %', current_timestamp;
 6             0           0             0    else
 7          5000    10226986          2281      perform pg_sleep(0.001);
 8             0           0             0    end if;
 9         10000          20             9    return input;
10             0           0             0  end;
11             0           0             0 
12             0           0             0 
13          5000        6976            70 

My questions:

  1. The linestats output includes three lines that are beyond the end of the function. Worse, the "imaginary" line 13 has a non-zero stats. How should that data be interpreted, or is it a bug?
  2. Based on the documentation, I would have expected the sum of all lines to be equal to the function total, but that's obviously not the case here - there appears to be double-counting across lines 2, 3 and 7, such that the sum of total_time across all lines is three times higher than the actual function total. Is this expected? The examples given don't exhibit this behaviour, here for example, the lines nicely sum to the total (there's no time taken for the BEGIN line).

Not compatible with 32-bit: error: lvalue required as unary ‘&’ operand

While building the Debian package for plprofiler I noticed it's failing on all 32-bit distributions we support:

16:09:11 ### PostgreSQL 15 build ###
16:09:11 make[2]: Entering directory '/<<PKGBUILDDIR>>/build-15'
16:09:11 gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I. -I/<<PKGBUILDDIR>> -I/usr/include/postgresql/15/server -I/usr/include/postgresql/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2   -c -o plprofiler.o /<<PKGBUILDDIR>>/plprofiler.c
16:09:11 In file included from /<<PKGBUILDDIR>>/plprofiler.c:20:
16:09:11 /<<PKGBUILDDIR>>/plprofiler.c: In function ‘pl_profiler_funcs_source’:
16:09:11 /usr/include/postgresql/15/server/postgres.h:804:47: error: lvalue required as unary ‘&’ operand
16:09:11   804 | #define Int64GetDatumFast(X)  PointerGetDatum(&(X))
16:09:11       |                                               ^
16:09:11 /usr/include/postgresql/15/server/postgres.h:600:38: note: in definition of macro ‘PointerGetDatum’
16:09:11   600 | #define PointerGetDatum(X) ((Datum) (X))
16:09:11       |                                      ^
16:09:11 /<<PKGBUILDDIR>>/plprofiler.c:1829:39: note: in expansion of macro ‘Int64GetDatumFast’
16:09:11  1829 |                         values[i++] = Int64GetDatumFast(line_number++);
16:09:11       |                                       ^~~~~~~~~~~~~~~~~
16:09:11 make[2]: *** [<builtin>: plprofiler.o] Error 1

Full log: https://pgdgbuild.dus.dg-i.net/job/plprofiler-binaries/2/architecture=i386,distribution=sid/console

Is that intended?

Compatibility/Updates with Postgres 16

Recently when I tried to build this extension with latest postgres 16, it threw errors like below

plprofiler.c: In function ‘pl_profiler_get_stack’:
plprofiler.c:1254:24: warning: passing argument 1 of ‘PointerGetDatum’ makes pointer from integer without a cast [-Wint-conversion]
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(funcdefs, nelems,
                        ^
../../src/include/fmgr.h:361:53: note: in definition of macro ‘PG_RETURN_POINTER’
 #define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                     ^
plprofiler.c:1254:2: note: in expansion of macro ‘PG_RETURN_ARRAYTYPE_P’
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(funcdefs, nelems,
  ^~~~~~~~~~~~~~~~~~~~~
In file included from plprofiler.c:20:0:
../../src/include/postgres.h:322:1: note: expected ‘const void *’ but argument is of type ‘Datum {aka long unsigned int}’
 PointerGetDatum(const void *X)
 ^~~~~~~~~~~~~~~
In file included from ../../src/include/postgres.h:45:0,
                 from plprofiler.c:20:
plprofiler.c: In function ‘pl_profiler_callgraph_local’:
../../src/include/c.h:916:7: error: static assertion failed: "entry->totalTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1502:18: note: in expansion of macro ‘Int64GetDatumFast’
    values[j++] = Int64GetDatumFast(entry->totalTime);
                  ^~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: error: static assertion failed: "entry->childTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1503:18: note: in expansion of macro ‘Int64GetDatumFast’
    values[j++] = Int64GetDatumFast(entry->childTime);
                  ^~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: error: static assertion failed: "entry->selfTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1504:18: note: in expansion of macro ‘Int64GetDatumFast’
    values[j++] = Int64GetDatumFast(entry->selfTime);
                  ^~~~~~~~~~~~~~~~~
plprofiler.c: In function ‘pl_profiler_callgraph_shared’:
../../src/include/c.h:916:7: error: static assertion failed: "entry->totalTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1598:17: note: in expansion of macro ‘Int64GetDatumFast’
   values[j++] = Int64GetDatumFast(entry->totalTime);
                 ^~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: error: static assertion failed: "entry->childTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1599:17: note: in expansion of macro ‘Int64GetDatumFast’
   values[j++] = Int64GetDatumFast(entry->childTime);
                 ^~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: error: static assertion failed: "entry->selfTime does not have type int64"
  do { _Static_assert(condition, errmessage); } while(0)
       ^
../../src/include/c.h:918:13: note: in expansion of macro ‘StaticAssertStmt’
  ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
             ^~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: in expansion of macro ‘StaticAssertExpr’
  (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
   ^~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: in expansion of macro ‘AssertVariableIsOfTypeMacro’
  (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
plprofiler.c:1600:17: note: in expansion of macro ‘Int64GetDatumFast’
   values[j++] = Int64GetDatumFast(entry->selfTime);
                 ^~~~~~~~~~~~~~~~~
In file included from ../../src/include/access/skey.h:19:0,
                 from ../../src/include/access/genam.h:18,
                 from ../../src/include/access/amapi.h:15,
                 from ../../src/include/access/hash.h:20,
                 from plprofiler.h:26,
                 from plprofiler.c:22:
plprofiler.c: In function ‘pl_profiler_func_oids_local’:
plprofiler.c:1665:24: warning: passing argument 1 of ‘PointerGetDatum’ makes pointer from integer without a cast [-Wint-conversion]
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
                        ^
../../src/include/fmgr.h:361:53: note: in definition of macro ‘PG_RETURN_POINTER’
 #define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                     ^
plprofiler.c:1665:2: note: in expansion of macro ‘PG_RETURN_ARRAYTYPE_P’
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
  ^~~~~~~~~~~~~~~~~~~~~
In file included from plprofiler.c:20:0:
../../src/include/postgres.h:322:1: note: expected ‘const void *’ but argument is of type ‘Datum {aka long unsigned int}’
 PointerGetDatum(const void *X)
 ^~~~~~~~~~~~~~~
In file included from ../../src/include/access/skey.h:19:0,
                 from ../../src/include/access/genam.h:18,
                 from ../../src/include/access/amapi.h:15,
                 from ../../src/include/access/hash.h:20,
                 from plprofiler.h:26,
                 from plprofiler.c:22:
plprofiler.c: In function ‘pl_profiler_func_oids_shared’:
plprofiler.c:1727:24: warning: passing argument 1 of ‘PointerGetDatum’ makes pointer from integer without a cast [-Wint-conversion]
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
                        ^
../../src/include/fmgr.h:361:53: note: in definition of macro ‘PG_RETURN_POINTER’
 #define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                     ^
plprofiler.c:1727:2: note: in expansion of macro ‘PG_RETURN_ARRAYTYPE_P’
  PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
  ^~~~~~~~~~~~~~~~~~~~~
In file included from plprofiler.c:20:0:
../../src/include/postgres.h:322:1: note: expected ‘const void *’ but argument is of type ‘Datum {aka long unsigned int}’
 PointerGetDatum(const void *X)
 ^~~~~~~~~~~~~~~
make[1]: *** [plprofiler.o] Error 1
make[1]: *** Waiting for unfinished jobs....
plprofiler.c:1254:24: warning: incompatible integer to pointer conversion passing 'Datum' (aka 'unsigned long') to parameter of type
      'const void *' [-Wint-conversion]
        PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(funcdefs, nelems,
        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/utils/array.h:258:54: note: expanded from macro 'PG_RETURN_ARRAYTYPE_P'
#define PG_RETURN_ARRAYTYPE_P(x)          PG_RETURN_POINTER(x)
                                          ~~~~~~~~~~~~~~~~~~^~
../../src/include/fmgr.h:361:53: note: expanded from macro 'PG_RETURN_POINTER'
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                    ^
../../src/include/postgres.h:322:29: note: passing argument to parameter 'X' here
PointerGetDatum(const void *X)
                            ^
plprofiler.c:1502:18: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->totalTime), int64)'
      "entry->totalTime does not have type int64"
                        values[j++] = Int64GetDatumFast(entry->totalTime);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1503:18: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->childTime), int64)'
      "entry->childTime does not have type int64"
                        values[j++] = Int64GetDatumFast(entry->childTime);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1504:18: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->selfTime), int64)'
      "entry->selfTime does not have type int64"
                        values[j++] = Int64GetDatumFast(entry->selfTime);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1598:17: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->totalTime), int64)'
      "entry->totalTime does not have type int64"
                values[j++] = Int64GetDatumFast(entry->totalTime);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1599:17: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->childTime), int64)'
      "entry->childTime does not have type int64"
                values[j++] = Int64GetDatumFast(entry->childTime);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1600:17: error: static_assert failed due to requirement '__builtin_types_compatible_p(typeof (entry->selfTime), int64)'
      "entry->selfTime does not have type int64"
                values[j++] = Int64GetDatumFast(entry->selfTime);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/postgres.h:550:3: note: expanded from macro 'Int64GetDatumFast'
        (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:962:3: note: expanded from macro 'AssertVariableIsOfTypeMacro'
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:918:13: note: expanded from macro 'StaticAssertExpr'
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/c.h:916:7: note: expanded from macro 'StaticAssertStmt'
        do { _Static_assert(condition, errmessage); } while(0)
             ^              ~~~~~~~~~
plprofiler.c:1665:24: warning: incompatible integer to pointer conversion passing 'Datum' (aka 'unsigned long') to parameter of type
      'const void *' [-Wint-conversion]
        PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/utils/array.h:258:54: note: expanded from macro 'PG_RETURN_ARRAYTYPE_P'
#define PG_RETURN_ARRAYTYPE_P(x)          PG_RETURN_POINTER(x)
                                          ~~~~~~~~~~~~~~~~~~^~
../../src/include/fmgr.h:361:53: note: expanded from macro 'PG_RETURN_POINTER'
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                    ^
../../src/include/postgres.h:322:29: note: passing argument to parameter 'X' here
PointerGetDatum(const void *X)
                            ^
plprofiler.c:1727:24: warning: incompatible integer to pointer conversion passing 'Datum' (aka 'unsigned long') to parameter of type
      'const void *' [-Wint-conversion]
        PG_RETURN_ARRAYTYPE_P(PointerGetDatum(construct_array(result, i,
        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/include/utils/array.h:258:54: note: expanded from macro 'PG_RETURN_ARRAYTYPE_P'
#define PG_RETURN_ARRAYTYPE_P(x)          PG_RETURN_POINTER(x)
                                          ~~~~~~~~~~~~~~~~~~^~
../../src/include/fmgr.h:361:53: note: expanded from macro 'PG_RETURN_POINTER'
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
                                                    ^
../../src/include/postgres.h:322:29: note: passing argument to parameter 'X' here
PointerGetDatum(const void *X)
                            ^
3 warnings and 6 errors generated.

After some investigation, I think it's because community changed definition of Int64GetDatumFast postgres/postgres@c8b2ef0#diff-eacba6996e6eb6b6a80a36b056cb95fa3ca94b57d8a30cb5de6bffd251687fafR897
from:

#define Int64GetDatumFast(X)  Int64GetDatum(X)

to:

#define Int64GetDatumFast(X) \
(AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))

while in plprofiler code, the variable is uint64 https://github.com/bigsql/plprofiler/blob/master/plprofiler.h#L160

Is it possible that this issue get fixed in the future release? And when can I expect a postgres16 compatible version to be released? Thank you!

Pldebugger

Will it be possible to make it compatible with the pldebbuger debugger? If the library plprofiler.co extension is in shared_preload_libraries then the debugger does not work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.