mmottl / postgresql-ocaml Goto Github PK
View Code? Open in Web Editor NEWOCaml-bindings for the PostgreSQL database
License: Other
OCaml-bindings for the PostgreSQL database
License: Other
Two suggested improvements on:
postgresql-ocaml/src/postgresql_stubs.c
Line 493 in 0f15dd4
The implementation of caml_alloc_final in the OCaml runtime system needs to wrap the finalizer into a full "custom operations" struct. This is cached, but the lookup in the cache is a linear scan. So a program that uses a lot of caml_alloc_final with different finalization functions can get some overhead. It is better to use directly caml_alloc_custom in user code.
The ratio 1/500 seems a bit high. It implies a major cycle every 500 allocations of a result. I don't know how much of an overhead a "result" represents in the postgresql client library, but if it's not too high, it might be good to reduce the ratio. One could also expose an explicit function to release a result value explicitly (before the GC collects the OCaml wrapper).
Sorry for the sparse report, I'm not sure where the issue is exactly at this point given there are quite a few pieces that changed all at once!
Running into a problem with a missing symbol, _PQbackendPID
:
Error: Error on dynamically loaded library: /Users/s/.esy/3_______________________________________________________________________/i/opam__s__postgresql-opam__c__4.3.0-4180f521/lib/stublibs/dllpostgresql_stubs.so: dlopen(/Users/s/.esy/3_______________________________________________________________________/i/opam__s__postgresql-opam__c__4.3.0-4180f521/lib/stublibs/dllpostgresql_stubs.so, 10): Symbol not found: _PQbackendPID
Referenced from: /Users/s/.esy/3_______________________________________________________________________/i/opam__s__postgresql-opam__c__4.3.0-4180f521/lib/stublibs/dllpostgresql_stubs.so
Expected in: flat namespace
in /Users/s/.esy/3_______________________________________________________________________/i/opam__s__postgresql-opam__c__4.3.0-4180f521/lib/stublibs/dllpostgresql_stubs.so
Looking at a list of the symbols in the .so
:
❯ nm /Users/s/.esy/3_______________________________________________________________________/i/opam__s__postgresql-opam__c__4.3.0-4180f521/lib/stublibs/dllpostgresql_stubs.so
U _Caml_state
0000000000005ba0 T _PQCancel_stub
U _PQbackendPID
0000000000003b80 T _PQbackendPID_stub
0000000000003b90 T _PQbackendPID_stub_bc
U _PQbinaryTuples
0000000000004810 T _PQbinaryTuples_stub
U _PQcancel
U _PQclear
U _PQcmdStatus
0000000000005050 T _PQcmdStatus_stub
U _PQcmdTuples
00000000000050d0 T _PQcmdTuples_stub
00000000000030f0 T _PQconn_isnull
U _PQconndefaults
00000000000032c0 T _PQconndefaults_stub
U _PQconnectPoll
0000000000003610 T _PQconnectPoll_stub
U _PQconnectStart
U _PQconnectdb
0000000000003110 T _PQconnectdb_stub
U _PQconninfoFree
U _PQconsumeInput
0000000000005af0 T _PQconsumeInput_stub
0000000000005b00 T _PQconsumeInput_stub_bc
U _PQdb
0000000000003760 T _PQdb_stub
U _PQdescribePrepared
00000000000045d0 T _PQdescribePrepared_stub
U _PQendcopy
00000000000065c0 T _PQendcopy_stub
0000000000006640 T _PQendcopy_stub_bc
U _PQerrorMessage
0000000000003b00 T _PQerrorMessage_stub
U _PQescapeByteaConn
0000000000005da0 T _PQescapeByteaConn_stub
0000000000005e00 T _PQescapeByteaConn_stub_bc
U _PQescapeStringConn
0000000000005cf0 T _PQescapeStringConn_stub
0000000000005d80 T _PQescapeStringConn_stub_bc
U _PQexec
U _PQexecParams
0000000000003c00 T _PQexecParams_stub
U _PQexecPrepared
0000000000004190 T _PQexecPrepared_stub
U _PQfformat
0000000000004a40 T _PQfformat_stub
0000000000004a60 T _PQfformat_stub_bc
U _PQfinish
00000000000031c0 T _PQfinish_stub
U _PQflush
0000000000005b40 T _PQflush_stub
0000000000005b50 T _PQflush_stub_bc
U _PQfmod
0000000000004ac0 T _PQfmod_stub
0000000000004ae0 T _PQfmod_stub_bc
U _PQfname
0000000000004830 T _PQfname_stub
00000000000048b0 T _PQfname_stub_bc
U _PQfnumber
0000000000004a00 T _PQfnumber_stub
0000000000004a20 T _PQfnumber_stub_bc
U _PQfreeCancel
U _PQfreemem
U _PQfsize
0000000000004b00 T _PQfsize_stub
0000000000004b20 T _PQfsize_stub_bc
U _PQftype
0000000000004a80 T _PQftype_stub
0000000000004aa0 T _PQftype_stub_bc
U _PQgetCancel
U _PQgetResult
0000000000005a40 T _PQgetResult_stub
0000000000004c90 T _PQgetescval_stub
0000000000004fa0 T _PQgetescval_stub_bc
U _PQgetisnull
0000000000004fc0 T _PQgetisnull_stub
0000000000004fe0 T _PQgetisnull_stub_bc
U _PQgetlength
0000000000005010 T _PQgetlength_stub
0000000000005030 T _PQgetlength_stub_bc
U _PQgetline
U _PQgetlineAsync
0000000000006260 T _PQgetlineAsync_stub
0000000000006280 T _PQgetlineAsync_stub_bc
00000000000060d0 T _PQgetline_stub
0000000000006190 T _PQgetline_stub_bc
U _PQgetvalue
0000000000004b80 T _PQgetvalue_stub
0000000000004c70 T _PQgetvalue_stub_bc
U _PQhost
00000000000038e0 T _PQhost_stub
U _PQisBusy
0000000000005b20 T _PQisBusy_stub
U _PQisnonblocking
0000000000005270 T _PQisnonblocking_stub
U _PQmakeEmptyPGresult
0000000000005190 T _PQmakeEmptyPGresult_stub
U _PQnfields
00000000000047d0 T _PQnfields_stub
00000000000047f0 T _PQnfields_stub_bc
U _PQnotifies
0000000000005f50 T _PQnotifies_stub
U _PQnparams
00000000000049c0 T _PQnparams_stub
00000000000049e0 T _PQnparams_stub_bc
U _PQntuples
0000000000004790 T _PQntuples_stub
00000000000047b0 T _PQntuples_stub_bc
0000000000002f90 T _PQocaml_init
U _PQoidValue
0000000000005150 T _PQoidValue_stub
0000000000005170 T _PQoidValue_stub_bc
U _PQoptions
0000000000003a60 T _PQoptions_stub
U _PQparamtype
0000000000004b40 T _PQparamtype_stub
0000000000004b60 T _PQparamtype_stub_bc
U _PQpass
0000000000003860 T _PQpass_stub
U _PQport
0000000000003960 T _PQport_stub
U _PQprepare
0000000000004050 T _PQprepare_stub
U _PQputline
00000000000062b0 T _PQputline_stub
0000000000006370 T _PQputline_stub_bc
U _PQputnbytes
0000000000006430 T _PQputnbytes_stub
00000000000064f0 T _PQputnbytes_stub_bc
U _PQresStatus
00000000000046e0 T _PQresStatus_stub
0000000000003be0 T _PQres_isnull
U _PQreset
U _PQresetPoll
00000000000036f0 T _PQresetPoll_stub
U _PQresetStart
0000000000003680 T _PQresetStart_stub
0000000000003240 T _PQreset_stub
U _PQresultErrorField
0000000000004930 T _PQresultErrorField_stub
U _PQresultErrorMessage
0000000000004710 T _PQresultErrorMessage_stub
U _PQresultStatus
00000000000046c0 T _PQresultStatus_stub
U _PQsendDescribePortal
00000000000059e0 T _PQsendDescribePortal_stub
00000000000059f0 T _PQsendDescribePortal_stub_bc
U _PQsendDescribePrepared
00000000000059b0 T _PQsendDescribePrepared_stub
00000000000059c0 T _PQsendDescribePrepared_stub_bc
U _PQsendPrepare
0000000000005600 T _PQsendPrepare_stub
0000000000005620 T _PQsendPrepare_stub_bc
U _PQsendQuery
U _PQsendQueryParams
0000000000005290 T _PQsendQueryParams_stub
00000000000055f0 T _PQsendQueryParams_stub_bc
U _PQsendQueryPrepared
0000000000005640 T _PQsendQueryPrepared_stub
00000000000059a0 T _PQsendQueryPrepared_stub_bc
U _PQserverVersion
0000000000003bb0 T _PQserverVersion_stub
0000000000003bc0 T _PQserverVersion_stub_bc
U _PQsetNoticeProcessor
00000000000066c0 T _PQsetNoticeProcessor_stub
U _PQsetSingleRowMode
0000000000005a10 T _PQsetSingleRowMode_stub
0000000000005a20 T _PQsetSingleRowMode_stub_bc
U _PQsetnonblocking
0000000000005230 T _PQsetnonblocking_stub
0000000000005250 T _PQsetnonblocking_stub_bc
U _PQsocket
0000000000005b70 T _PQsocket_stub
0000000000005b80 T _PQsocket_stub_bc
U _PQstatus
0000000000003ae0 T _PQstatus_stub
U _PQtty
00000000000039e0 T _PQtty_stub
U _PQunescapeBytea
0000000000005e60 T _PQunescapeBytea_stub
U _PQuser
00000000000037e0 T _PQuser_stub
U __DefaultRuneLocale
U ___maskrune
U ___stack_chk_fail
U ___stack_chk_guard
000000000000c380 d __dyld_private
0000000000004df0 t _bytea_hex_pairs
U _caml_alloc_custom
U _caml_alloc_small
U _caml_alloc_string
U _caml_alloc_tuple
U _caml_callback
U _caml_copy_string
U _caml_enter_blocking_section
U _caml_failwith
U _caml_leave_blocking_section
U _caml_modify
U _caml_named_value
U _caml_raise_with_arg
U _caml_register_generational_global_root
U _caml_remove_generational_global_root
U _caml_stat_alloc
U _caml_stat_free
U _caml_string_length
0000000000004eb0 t _decode_bytea_hex
0000000000007f00 s _error_field_tbl
0000000000007770 t _free_result
0000000000002fe0 T _ftype_of_oid_stub
0000000000003040 T _ftype_of_oid_stub_bc
U _lo_close
0000000000006cb0 T _lo_close_stub
0000000000006d30 T _lo_close_stub_bc
U _lo_creat
0000000000006780 T _lo_creat_stub
0000000000006800 T _lo_creat_stub_bc
U _lo_export
0000000000006a00 T _lo_export_stub
0000000000006ac0 T _lo_export_stub_bc
U _lo_import
0000000000006880 T _lo_import_stub
0000000000006940 T _lo_import_stub_bc
U _lo_lseek
0000000000007600 T _lo_lseek_stub
00000000000076b0 T _lo_lseek_stub_bc
U _lo_open
0000000000006b90 T _lo_open_stub
0000000000006c20 T _lo_open_stub_bc
U _lo_read
0000000000007190 T _lo_read_ba_stub
0000000000007240 T _lo_read_ba_stub_bc
0000000000006fe0 T _lo_read_stub
00000000000070b0 T _lo_read_stub_bc
U _lo_tell
0000000000006dc0 T _lo_tell_stub
0000000000006e40 T _lo_tell_stub_bc
U _lo_unlink
0000000000006ed0 T _lo_unlink_stub
0000000000006f50 T _lo_unlink_stub_bc
U _lo_write
00000000000074a0 T _lo_write_ba_stub
0000000000007550 T _lo_write_ba_stub_bc
00000000000072f0 T _lo_write_stub
00000000000073c0 T _lo_write_stub_bc
U _memcpy
0000000000006740 t _notice_ml
00000000000030b0 T _oid_of_ftype_stub
00000000000030d0 T _oid_of_ftype_stub_bc
000000000000c3a0 d _oid_tbl
000000000000c498 d _result_ops
U _strlen
000000000000c390 d _v_empty_string
000000000000c4d8 b _v_exc_Oid
000000000000c4e0 b _v_null_param
U dyld_stub_binder
Appreciate any pointers you might have on how to start tracking this down!
Postgresql_compat is missing from the installed libraries for postgresql.2.1.1 in the 4.01.0 switch of opam. E.g. loading postgresql from topfind gives "Error: Reference to undefined global `Postgresql_compat'".
According to the postgres documentation and source code, the return code of PQCancel
is 1 when dispatch is successful and 0 otherwise.
However, PQCancel_stub
seem to interpret 0 as success and non-zero as failure, with is exactly the opposite.
I want to select
one data from database, the following code print nothing:
let insert_ua ua =
let conn = connect () in
let s_q = "select log_id from devices where ua='' limit 1" in
conn#send_query s_q;
match conn#get_result with
| Some res -> begin
match res#status with
| Tuples_ok ->
printf "%d-%d-%s, " 0 0 (res#getvalue 0 0)
| _ -> printf "wtf\n";
end
| None -> ()
However, the following prints the data I need: 0-0-9,
.
let insert_ua ua =
let conn = connect () in
let s_q = "select log_id from devices where ua='' limit 1" in
conn#send_query s_q;
match conn#get_result with
| Some res -> begin
match res#status with
| Tuples_ok ->
for tuple = 0 to res#ntuples - 1 do
for field = 0 to res#nfields - 1 do
printf "%d-%d-%s, " tuple field (res#getvalue tuple field)
done;
print_newline ()
done
| _ -> printf "wtf\n";
end
| None -> ()
I don't know what's the difference between these two functions, since the tuple
and field
are both 0
in my case.
I had a look over your discover.ml script and glancing over these lines:
postgresql-ocaml/src/config/discover.ml
Lines 54 to 64 in 916bb7b
I find this code a bit weird. We're constructing this conf
record simply to access its fields. Which doesn't seem too useful.Are you forgetting to actually call C.Pkg_config.query
to respect the user's pkg-config settings whenever they're available?
I found an issue when registering a notice processor when using asynchronous request which triggers a notice. The issue can be reproduced by the following code
let statements = [
"CREATE TEMPORARY TABLE notice_processor_and_async_1 \
(id serial PRIMARY KEY, name text NOT NULL)";
"CREATE TEMPORARY TABLE notice_processor_and_async_2 \
(id integer PRIMARY KEY REFERENCES notice_processor_and_async_1)";
"DROP TABLE notice_processor_and_async_1 CASCADE";
]
let wait_for_result c =
c#consume_input;
while c#is_busy do
ignore (Unix.select [Obj.magic c#socket] [] [] (-.1.0));
c#consume_input
done
let fetch_result c = wait_for_result c; c#get_result
let fetch_single_result c =
match fetch_result c with
| None -> assert false
| Some r -> assert (fetch_result c = None); r
let () = Printexc.register_printer @@ function
| Postgresql.Error err -> Some (Postgresql.string_of_error err)
| _ -> None
let () =
let conn = new Postgresql.connection ~conninfo:Sys.argv.(1) () in
conn#set_notice_processor print_endline;
statements |> List.iter begin fun stmt ->
conn#send_query stmt;
let r = fetch_single_result conn in
assert (r#status = Postgresql.Command_ok)
end
The following backtrace shows that it gets stuck in caml_leave_blocking_section
in the notice_ml
wrapper trying to acquire a caml_master_lock
.
(gdb) run postgresql://
Starting program: /home/urkedal/proj/postgresql-ocaml/_build/default/examples/notice_processor_and_async.exe postgresql://
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
^C
Program received signal SIGINT, Interrupt.
0x00007ffff76739f3 in futex_wait_cancelable (private=<optimized out>, expected=0,
futex_word=0x5555558ac458 <caml_master_lock+88>) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
88 ../sysdeps/unix/sysv/linux/futex-internal.h: No such file or directory.
(gdb) bt
#0 0x00007ffff76739f3 in futex_wait_cancelable (private=<optimized out>, expected=0,
futex_word=0x5555558ac458 <caml_master_lock+88>) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1 __pthread_cond_wait_common (abstime=0x0, mutex=0x5555558ac400 <caml_master_lock>,
cond=0x5555558ac430 <caml_master_lock+48>) at pthread_cond_wait.c:502
#2 __pthread_cond_wait (cond=0x5555558ac430 <caml_master_lock+48>, mutex=0x5555558ac400 <caml_master_lock>)
at pthread_cond_wait.c:655
#3 0x00005555556225be in st_masterlock_acquire.constprop ()
#4 0x00005555556225f9 in caml_thread_leave_blocking_section ()
#5 0x000055555562bdb6 in caml_leave_blocking_section () at signals.c:167
#6 0x000055555561db21 in notice_ml (cb=0x5555558c3750,
msg=0x555555923880 "NOTICE: drop cascades to constraint notice_processor_and_async_2_id_fkey on table notice_processor_and_async_2\n") at postgresql_stubs.c:1404
#7 0x00007ffff78a335a in ?? () from /usr/lib/x86_64-linux-gnu/libpq.so.5
#8 0x00007ffff78a365a in ?? () from /usr/lib/x86_64-linux-gnu/libpq.so.5
#9 0x00007ffff789a296 in PQisBusy () from /usr/lib/x86_64-linux-gnu/libpq.so.5
#10 0x000055555562043c in PQisBusy_stub (v_conn=<optimized out>) at postgresql_stubs.c:1107
#11 0x00005555555dcc2c in camlPostgresql__fun_2904 () at src/postgresql.ml:1121
#12 0x00005555555dac15 in camlPostgresql__protectx_963 () at src/postgresql.ml:755
#13 0x00005555555d1f6e in camlNotice_processor_and_async__wait_for_result_81 () at examples/notice_processor_and_async.ml:11
#14 0x00005555555d203d in camlNotice_processor_and_async__fetch_result_191 () at examples/notice_processor_and_async.ml:16
#15 0x00005555555d206d in camlNotice_processor_and_async__fetch_single_result_193 ()
at examples/notice_processor_and_async.ml:19
#16 0x00005555555d21e5 in camlNotice_processor_and_async__fun_649 () at examples/notice_processor_and_async.ml:32
#17 0x00005555555ea1a1 in camlStdlib__list__iter_236 () at list.ml:110
#18 0x00005555555d23f6 in camlNotice_processor_and_async__entry () at examples/notice_processor_and_async.ml:30
#19 0x00005555555ceaa9 in caml_program ()
#20 0x0000555555647c10 in caml_start_program ()
#21 0x000055555562a995 in caml_startup_common (argv=0x7fffffffd458, pooling=<optimized out>, pooling@entry=0)
at startup_nat.c:160
#22 0x000055555562a9fb in caml_startup_exn (argv=<optimized out>) at startup_nat.c:165
#23 caml_startup (argv=<optimized out>) at startup_nat.c:170
#24 0x00005555555ce6ec in main (argc=<optimized out>, argv=<optimized out>) at main.c:44
I'm not sure it it's the async code or the notice processor mechanism which is the issue, but
I noticed the comment in notice_ml
: It mentions segfault as potential issue, but if the lock is held, I guess a deadlock could also be a plausible symptom? And could the later contribution of async binding have affected the assumptions?
Is it possible to add an Lwt/non blocking layer? I mean for this library to provide it.
OPAM is failing to download some historic releases;
Building /home/opam/opam-repository/archives/postgresql.2.0.9+opam.tar.gz
[postgresql.2.0.9] Downloading https://github.com/mmottl/postgresql-ocaml/releases/download/v2.0.9/postgresql-ocaml-2.0.9.tar.gz
[ERROR] curl: code 404 while downloading https://github.com/mmottl/postgresql-ocaml/releases/download/v2.0.9/postgresql-ocaml-2.0.9.tar.gz
[ERROR] https://github.com/mmottl/postgresql-ocaml/releases/download/v2.0.9/postgresql-ocaml-2.0.9.tar.gz is not available
Building /home/opam/opam-repository/archives/postgresql.2.1.0+opam.tar.gz
[postgresql.2.1.0] Downloading https://github.com/mmottl/postgresql-ocaml/releases/download/v2.1.0/postgresql-ocaml-2.1.0.tar.gz
[ERROR] curl: code 404 while downloading https://github.com/mmottl/postgresql-ocaml/releases/download/v2.1.0/postgresql-ocaml-2.1.0.tar.gz
[ERROR] https://github.com/mmottl/postgresql-ocaml/releases/download/v2.1.0/postgresql-ocaml-2.1.0.tar.gz is not available
The following failure has been detected with check.ocamllabs.io:
+ /home/opam/.opam/4.09.0/bin/dune "build" "-p" "postgresql" "-j" "71" (CWD=/home/opam/.opam/4.09.0/.opam-switch/build/postgresql.4.5.0)
- discover src/c_flags.sexp,src/c_library_flags.sexp (exit 2)
- (cd _build/default/src && config/discover.exe)
- Unable to find versions from line 'PostgreSQL 12rc1 (Debian 12~rc1-1)', cmd: 'pg_config --includedir --libdir --version'run: /home/opam/.opam/4.09.0/bin/ocamlc.opt -config
- -> process exited with code 0
- -> stdout:
- | version: 4.09.0
- | standard_library_default: /home/opam/.opam/4.09.0/lib/ocaml
- | standard_library: /home/opam/.opam/4.09.0/lib/ocaml
- | ccomp_type: cc
- | c_compiler: gcc
- | ocamlc_cflags: -O2 -fno-strict-aliasing -fwrapv -fPIC
- | ocamlc_cppflags: -D_FILE_OFFSET_BITS=64 -D_REENTRANT
- | ocamlopt_cflags: -O2 -fno-strict-aliasing -fwrapv
- | ocamlopt_cppflags: -D_FILE_OFFSET_BITS=64 -D_REENTRANT
- | bytecomp_c_compiler: gcc -O2 -fno-strict-aliasing -fwrapv -fPIC -D_FILE_OFFSET_BITS=64 -D_REENTRANT
- | native_c_compiler: gcc -O2 -fno-strict-aliasing -fwrapv -D_FILE_OFFSET_BITS=64 -D_REENTRANT
- | bytecomp_c_libraries: -lm -ldl -lpthread
- | native_c_libraries: -lm -ldl
- | native_pack_linker: ld -r -o
- | ranlib: ranlib
- | architecture: amd64
- | model: default
- | int_size: 63
- | word_size: 64
- | system: linux
- | asm: as
- | asm_cfi_supported: true
- | with_frame_pointers: false
- | ext_exe:
- | ext_obj: .o
- | ext_asm: .s
- | ext_lib: .a
- | ext_dll: .so
- | os_type: Unix
- | default_executable_name: a.out
- | systhread_supported: true
- | host: x86_64-pc-linux-gnu
- | target: x86_64-pc-linux-gnu
- | flambda: false
- | spacetime: false
- | safe_string: false
- | default_safe_string: true
- | flat_float_array: true
- | afl_instrument: false
- | windows_unicode: false
- | supports_shared_libraries: true
- | exec_magic_number: Caml1999X026
- | cmi_magic_number: Caml1999I026
- | cmo_magic_number: Caml1999O026
- | cma_magic_number: Caml1999A026
- | cmx_magic_number: Caml1999Y026
- | cmxa_magic_number: Caml1999Z026
- | ast_impl_magic_number: Caml1999M026
- | ast_intf_magic_number: Caml1999N026
- | cmxs_magic_number: Caml1999D026
- | cmt_magic_number: Caml1999T026
- -> stderr:
- Fatal error: exception Not_found
- Raised at file "string.ml", line 115, characters 19-34
- Called from file "string.ml" (inlined), line 119, characters 16-42
- Called from file "src/config/discover.ml", line 22, characters 26-51
- Re-raised at file "src/config/discover.ml", line 52, characters 35-44
- Called from file "src/exn.ml", line 66, characters 8-11
- Re-raised at file "src/exn.ml", line 69, characters 6-15
- Called from file "src/configurator/v1.ml", line 673, characters 4-7
- Re-raised at file "src/stdune/exn.ml" (inlined), line 39, characters 38-65
- Called from file "src/configurator/v1.ml", line 682, characters 6-37
- Called from file "src/config/discover.ml", line 6, characters 2-1023
[ERROR] The compilation of postgresql failed at "/home/opam/.opam/4.09.0/bin/dune build -p postgresql -j 71".
Basically the problem is that discover.ml
cannot find the version number because it seems to have changed from before since postgresql 12 (compiled fine with libpq-dev (11.5-2+b1)
):
Unable to find versions from line 'PostgreSQL 12rc1 (Debian 12~rc1-1)', cmd: 'pg_config --includedir --libdir --version'run: /home/opam/.opam/4.09.0/bin/ocamlc.opt -config
I've been getting seemingly “random” segmentation faults, I tried to run my server in GDB and it gave this:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe6d27700 (LWP 708)]
unescape_bytea_9x (v_from=<value optimized out>) at lib/postgresql_stubs.c:966
966 lib/postgresql_stubs.c: No such file or directory.
in lib/postgresql_stubs.c
The segmentation faults only happen with the PG backend of https://github.com/smondet/trakeva, exactly the same server works fine the Sqlite backend.
The PG server is on version 9.3.
I would suggest to use Postgresql.null for null value. This way physical equality
can distinguish the NULL value and the empty string. Accessing the result to know is a parameter is NULL is
a bit annoying.
This is relatively fragile as OCaml could decide to share the representation of the null string. This is not done in 5.0.0.
But even in this case, Postgresl.null could be created from C or in other ways to avoid sharing.
I'm trying to more robustly handle errors, and build up error objects with enough context to generate dev (and user)-friendly error messages.
From https://www.postgresql.org/docs/9.5/static/libpq-exec.html it looks like we should using PQresultErrorField
. https://www.postgresql.org/docs/current/static/protocol-error-fields.html looks like it has everything we need.
https://stackoverflow.com/questions/18645626/postgres-sqlstate-pqresulterrorfield-returns-null also has a code snippet, but looking at the current c-stubs, I don't think this is exposed right now.
PGresult* res = PQexec(conn, "SELECT * FROM foobar");
if (res) {
if (PQresultStatus(res)==PGRES_FATAL_ERROR) {
char* p = PQresultErrorField(res, PG_DIAG_SQLSTATE);
if (p) {
printf("sqlstate=%s\n", p?p:"null");
}
}
}
The link by clicking "online" in "The API-documentation can also be found online"
goes to http://mmottl.github.io/postgresql-ocaml/api/postgresql
which doesn't work.
Where can the API-documentation be found?
We're storing large binary data in our DB. We saw a 3x speedup when inserting the data using binary format, vs using escaped text.
However, I don't see a way to get binary data out of postgres without escaping it. I believe that is due to this line, in which the resultFormat is 0 (indicating text) with no way of setting it to 1.
Does this seem right? Can we add a way of setting it to 1 to get output as binary?
The special exception part of the license file says:
By "a publicly distributed version of the Library", we mean either the unmodified Library as distributed by the authors, or a modified version of the Library that is distributed under the conditions defined in clause 3 of the GNU Lesser General Public License.
It should be "clause 2", not "clause 3".
This is the same typo made in OCaml's license: ocaml/ocaml@2d26308
The class "connection" provides a few methods which deal with prepared SQL statements. I imagine that it will be useful to map this software area to an improved class hierarchy.
How do you think about to add a method like "create_prepared_statement" which will generate object instances instead of distinguishing SQL statements by the parameter "stm_name" of the method "prepare"?
Is there any example code for pg notification?
Since I upgraded from postgresql 4.0.1 to postgresql 4.1.0 via OPAM I have begun experiencing compilation errors when building postgresql database projects using OCaml 4.04.x.
Here is a minimal example a.ml
:
class pg_database = object(self)
val connection =
new Postgresql.connection ()
end
Compiling using ocamlopt
unexpectedly yields an "inconsistent assumptions" compiler error:
$ ocamlopt -v
The OCaml native-code compiler, version 4.04.2
Standard library directory: /home/dhil/.opam/4.04.2/lib/ocaml
$ ocamlopt -thread -I ~/.opam/4.04.2/lib/postgresql/ threads.cmxa postgresql.cmxa a.ml
File "a.ml", line 1:
Error: Files a.cmx and /home/dhil/.opam/4.04.2/lib/postgresql/postgresql.cmxa
make inconsistent assumptions over interface Postgresql
My understanding is that the error "inconsistent assumptions" occurs when linking two modules which have been compiled using two different OCaml compiler versions. Interestingly, I do not experience the error when I subvert OPAM and build postgres 4.1.0 from source myself:
$ wget https://github.com/mmottl/postgresql-ocaml/archive/4.1.0.tar.gz
$ tar zxf 4.1.0.tar.gz
$ cd postgresql-ocaml-4.1.0
$ make
$ cd ..
$ ocamlopt -thread -I ./postgresql-ocaml-4.1.0/_build/default/src/ threads.cmxa postgresql.cmxa a.ml
$ echo $?
0
Strangely, if I switch to OCaml 4.05.0 and install postgresql 4.1.0 via OPAM then the problem disappears:
$ ocamlopt -v
The OCaml native-code compiler, version 4.05.0
Standard library directory: /home/dhil/.opam/4.05.0/lib/ocaml
$ ocamlopt -thread -I ~/.opam/4.05.0/lib/postgresql/ unix.cmxa threads.cmxa postgresql.cmxa a.ml
$ echo $?
0
(ocamopt
4.05.0 requires unix.cmxa
to be explicitly linked in order to link threads.cmxa
).
I am wondering whether you can reproduce this issue? Also, I wonder whether this is an issue due to your packaging or a potential bug in OPAM?
Thank you for this awesome work!
I am getting a seg fault on OS X for the prompt_gtk.ml example on OS X.
On OS X 10.11.3, ocaml version 4.02.3, postgresql 9.5.1
installed via brew.
I added #require "posgresql, lablgtk2"
to the top and ran with
utop prompt_gtk.ml host=localhost
Then I get a seg fault
after these messages:
(process:18198): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:18198): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:18198): Gtk-WARNING **: Screen for GtkWindow not set; you must always set
a screen for a GtkWindow before using the window
(process:18198): Gdk-CRITICAL **: gdk_pango_context_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Pango-CRITICAL **: pango_context_set_font_description: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_language: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_new: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_text: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_alignment: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_ellipsize: assertion 'PANGO_IS_LAYOUT (layout)' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_single_paragraph_mode: assertion 'PANGO_IS_LAYOUT (layout)' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_width: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed
(process:18198): Gdk-CRITICAL **: gdk_pango_context_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Pango-CRITICAL **: pango_context_set_font_description: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_language: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Gdk-CRITICAL **: gdk_pango_context_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Pango-CRITICAL **: pango_context_set_font_description: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_language: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(process:18198): Gtk-CRITICAL **: gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_display: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_get: assertion 'G_IS_OBJECT (object)' failed
(process:18198): Pango-CRITICAL **: pango_layout_new: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_alignment: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_spacing: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_indent: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_text: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_attributes: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_width: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'layout != NULL' failed
(process:18198): Gdk-CRITICAL **: gdk_pango_context_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Pango-CRITICAL **: pango_context_set_font_description: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_language: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Gdk-CRITICAL **: gdk_pango_context_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Pango-CRITICAL **: pango_context_set_font_description: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_language: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_context_set_base_dir: assertion 'context != NULL' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(process:18198): Gtk-CRITICAL **: gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_display: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): GLib-GObject-CRITICAL **: g_object_get: assertion 'G_IS_OBJECT (object)' failed
(process:18198): Pango-CRITICAL **: pango_layout_new: assertion 'context != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_alignment: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_spacing: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_indent: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_text: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_set_attributes: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_width: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'layout != NULL' failed
(process:18198): Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'layout != NULL' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_default_colormap: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_colormap_get_visual: assertion 'GDK_IS_COLORMAP (colormap)' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_default_colormap: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_root_window: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_screen_get_root_window: assertion 'GDK_IS_SCREEN (screen)' failed
(process:18198): Gdk-CRITICAL **: gdk_window_new: assertion 'GDK_IS_WINDOW (parent)' failed
(process:18198): Gdk-CRITICAL **: gdk_window_set_user_data: assertion 'GDK_IS_WINDOW (window)' failed
(process:18198): Gtk-CRITICAL **: gtk_style_attach: assertion 'window != NULL' failed
(process:18198): Gtk-CRITICAL **: gtk_style_set_background: assertion 'GTK_IS_STYLE (style)' failed
(process:18198): Gtk-CRITICAL **: gtk_paint_flat_box: assertion 'GTK_IS_STYLE (style)' failed
[2] 18198 segmentation fault utop prompt_gtk.ml host=localhost
Should I not be using lablgtk
on OS X and instead be using the osx special gtk package?
Also, can you provide an example of what a connection string for these bindings out to look like?
I tried using strings of form: postgresql://something...:some_port
but it was rejected, something more meaty than just connecting to localhost would be greatly appreciated.
It can happen that I want to make changes to database contents more often permanent before the corresponding SQL statement or connection handle will be closed. Thus I am looking for ways to control a commit strategy.
I would also appreciate if a database rollback can be triggered explicitly when a special condition was detected by dedicated program logic.
I've adapted a part of the prompt.ml example to be able to get postgres notifications into this code:
let run () =
let rec dump_notification conn =
match conn#notifies with
| Some { Postgresql.Notification.name; pid; extra } ->
let () =
Lwt_preemptive.run_in_main (fun () ->
let () =
Logs.debug @@ fun m -> m "Notication from backend %i: [%s] [%s]\n" pid name extra
in
Lwt_mvar.put mvar (name, pid, extra))
in
dump_notification conn
| None ->
()
in
let listener conn =
try
while true do
let socket : Unix.file_descr = Caml.Obj.magic conn#socket in
let _ = Unix.select [ socket ] [] [] 1. in
let () = conn#consume_input in
dump_notification conn
done
with
| e ->
Logs.err @@ fun m -> m "%s" (Exn.to_string e)
in
Lwt.async (fun () ->
let conninfo = "postgresql://postgres:postgres@localhost:5432/board_games_dev" in
let conn = new Postgresql.connection ~conninfo () in
conn#exec ~expect:[ Command_ok ] "listen events" |> ignore ;
conn#set_notice_processor (fun s -> Fmt.pr "postgresql error [%s]\n" s) ;
Lwt_preemptive.detach listener conn) ;
And this crashes my program. I suspect that the consume_input
is where the crash happens although I'm not sure. Without the dump_notification
I can still get the code to crash although it seems that it takes longer to crash in that case.
Just to be clear, I'm not sure this is a bug in postgresql-ocaml or in my code or in a combination of usage with lwt and caqti.
And this is the backtrace I've been able to get:
Thread 1 "server.exe" received signal SIGSEGV, Segmentation fault.
0x0000000000000003 in ?? ()
(gdb) bt
#0 0x0000000000000003 in ?? ()
#1 0x00005555558bb043 in camlPostgresql__protectx_967 ()
#2 0x0000000000000001 in ?? ()
#3 0x00007ffff75c4bf8 in ?? ()
#4 0x00007ffff73ba940 in ?? ()
#5 0x00005555558ad08d in camlCaqti_driver_postgresql__aux_1952 ()
#6 0x00007fffffffdcb0 in ?? ()
#7 0x00005555558ad0b4 in camlCaqti_driver_postgresql__aux_1952 ()
#8 0x00007ffff75d6310 in ?? ()
#9 0x00007ffff75d64d0 in ?? ()
#10 0x0000000000000001 in ?? ()
#11 0x0000555555a4bfcb in camlLwt__callback_1225 ()
#12 0x00007fffffffe080 in ?? ()
#13 0x0000555555a4bfd4 in camlLwt__callback_1225 ()
#14 0x00007ffff75d5928 in ?? ()
#15 0xa87add3fe9485300 in ?? ()
#16 0x0000000000000001 in ?? ()
#17 0x0000555555a4abc8 in camlLwt__iter_callback_list_848 ()
#18 0x00007ffff75c4d70 in ?? ()
#19 0x0000000000000001 in ?? ()
#20 0x0000000000000017 in ?? ()
#21 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#22 0x00007ffff75c4db0 in ?? ()
#23 0x0000000000000001 in ?? ()
#24 0x00007ffff75d5a30 in ?? ()
#25 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#26 0x0000555555cd4ea8 in camlLwt__20 ()
#27 0x00007ffff75d5a30 in ?? ()
#28 0x00007fffffffe080 in ?? ()
#29 0x0000555555a4bff5 in camlLwt__callback_1225 ()
#30 0x00007ffff75d5a00 in ?? ()
#31 0x00007ffff75c4dd8 in ?? ()
#32 0x0000000000000001 in ?? ()
#33 0x0000555555a4abc8 in camlLwt__iter_callback_list_848 ()
#34 0x00007ffff75c4e18 in ?? ()
#35 0x0000000000000001 in ?? ()
#36 0x00007ffff75c5ad0 in ?? ()
#37 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#38 0x00007ffff75c4e58 in ?? ()
#39 0x0000000000000001 in ?? ()
#40 0x00007ffff75d5b08 in ?? ()
#41 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#42 0x0000555555cd4ea8 in camlLwt__20 ()
#43 0x00007ffff75d5b08 in ?? ()
#44 0x0000000000000002 in ?? ()
#45 0x0000555555a4cc97 in camlLwt__callback_1343 ()
#46 0x00007ffff75c4ee8 in ?? ()
#47 0x0000555555a4acfe in camlLwt__leave_resolution_loop_894 ()
#48 0x0000000000000001 in ?? ()
#49 0x0000555555a4abc8 in camlLwt__iter_callback_list_848 ()
#50 0x00007ffff75c4e80 in ?? ()
#51 0x0000000000000001 in ?? ()
#52 0x00007ffff75c5ba8 in ?? ()
#53 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#54 0x00007ffff75c4ec0 in ?? ()
#55 0x0000000000000001 in ?? ()
#56 0x00007ffff75d5be0 in ?? ()
#57 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#58 0x0000555555cd4ea8 in camlLwt__20 ()
#59 0x00007ffff75d5be0 in ?? ()
#60 0x00007fffffffe080 in ?? ()
#61 0x0000555555a4c82f in camlLwt__callback_1304 ()
#62 0x00007ffff75d5bb0 in ?? ()
#63 0x00007ffff75c4ee8 in ?? ()
#64 0x0000000000000001 in ?? ()
#65 0x0000555555a4abc8 in camlLwt__iter_callback_list_848 ()
#66 0x00007ffff75c4ef8 in ?? ()
#67 0x0000000000000001 in ?? ()
#68 0x00007ffff75c5c80 in ?? ()
#69 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#70 0x00007ffff75c4f38 in ?? ()
#71 0x0000000000000001 in ?? ()
#72 0x00007ffff75d5d40 in ?? ()
#73 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#74 0x0000555555cd4ea8 in camlLwt__20 ()
#75 0x00007ffff75d5d40 in ?? ()
#76 0x00007ffff75d5ce0 in ?? ()
#77 0x0000555555a4f98b in camlLwt__callback_1848 ()
#78 0x00007ffff75c5030 in ?? ()
#79 0x0000555555a4abf8 in camlLwt__iter_callback_list_848 ()
#80 0x00007ffff75c4f60 in ?? ()
#81 0x0000000000000001 in ?? ()
#82 0x0000000000000001 in ?? ()
#83 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#84 0x00007ffff75c4fa0 in ?? ()
#85 0x0000000000000001 in ?? ()
#86 0x00007ffff75d5e48 in ?? ()
#87 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#88 0x0000555555cd4ea8 in camlLwt__20 ()
#89 0x00007ffff75d5e48 in ?? ()
#90 0x00007ffff75c6168 in ?? ()
#91 0x0000555555a4cc97 in camlLwt__callback_1343 ()
#92 0x00007ffff75c5030 in ?? ()
#93 0x0000555555a4b9b8 in camlLwt__add_task_r_1142 ()
#94 0x00007ffff733d6c0 in ?? ()
#95 0x0000555555a4abc8 in camlLwt__iter_callback_list_848 ()
#96 0x00007ffff75c4fc8 in ?? ()
#97 0x0000000000000001 in ?? ()
#98 0x00007ffff73db6a0 in ?? ()
#99 0x0000555555a4ad39 in camlLwt__run_in_resolution_loop_899 ()
#100 0x00007ffff75c5008 in ?? ()
#101 0x0000000000000001 in ?? ()
#102 0x00007ffff75d60d8 in ?? ()
#103 0x0000555555a4aeeb in camlLwt__resolve_916 ()
#104 0x0000555555cd4ea8 in camlLwt__20 ()
#105 0x00007ffff75d60d8 in ?? ()
#106 0x00007ffff75d60b0 in ?? ()
#107 0x0000555555a4b120 in camlLwt__wakeup_general_951 ()
#108 0x00007ffff75c5040 in ?? ()
I've posted the issue on discuss.ocaml as well for more context: https://discuss.ocaml.org/t/how-to-debug-a-terminated-by-signal-sigsegv-address-boundary-error/5936
PQexecParams_stub takes a v_binary_result
argument, which tells postgres to use the text or binary format.
PQexecPrepared has the same argument, but the value is hardcoded to "text".
@mmottl: would you be opposed to me adding this functionality to postgresql-ocaml, and if not, do you foresee any issues that I may run into?
Simpley doing print_endline ("field type: " ^ string_of_field_type (r#ftype 0));
seems to cause my ocaml program to exit (with code 0 and output of Postgresql.Oid(2950)
, which is the uuid oid) when run against a query that returns a uuid column. I noticed uuid is not one of the types included in http://mmottl.github.io/postgresql-ocaml/api/Postgresql.html#TYPEftype - is there any way around this? Uuid are fairly critical to my use case, and it's important that they be stored as such for other consumers of the db.
on ocaml 4.06.1 (and 4.07.0) I'm getting an opam install error:
edit: this is on a new xps15 with Mint 19... Maybe there is a package I'm missing?
I also get the error with:
opam pin add postgresql [email protected]:mmottl/postgresql-ocaml.gittowards
=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[postgresql] Archive in cache
=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[ERROR] The compilation of postgresql failed at "jbuilder build -p postgresql
-j 4".
#=== ERROR while installing postgresql.4.4.0 ==================================#
# opam-version 1.2.2
# os linux
# command jbuilder build -p postgresql -j 4
# path /home/caseybasichis/.opam/4.06.1/build/postgresql.4.4.0
# compiler 4.06.1
# exit-code 1
# env-file /home/caseybasichis/.opam/4.06.1/build/postgresql.4.4.0/postgresql-17064-5f1023.env
# stdout-file /home/caseybasichis/.opam/4.06.1/build/postgresql.4.4.0/postgresql-17064-5f1023.out
# stderr-file /home/caseybasichis/.opam/4.06.1/build/postgresql.4.4.0/postgresql-17064-5f1023.err
### stderr ###
# -> stdout:
# [...]
# | ast_impl_magic_number: Caml1999M022
# | ast_intf_magic_number: Caml1999N022
# | cmxs_magic_number: Caml1999D022
# | cmt_magic_number: Caml1999T022
# -> stderr:
# Fatal error: exception End_of_file
# Raised at file "src/import0.ml" (inlined), line 237, characters 22-32
# Called from file "src/configurator.ml", line 511, characters 13-22
# Called from file "src/config/discover.ml", line 6, characters 2-1023
=-=- Error report -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The following actions failed
∗ install postgresql 4.4.0
No changes have been performed
=-=- postgresql.4.4.0 troobleshooting -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=> This package relies on external (system) dependencies that may be missing.
`opam depext postgresql.4.4.0' may help you find the correct installation
for your system.
A postgres test:
caseybasichis@caseybasichis-XPS-15-9570:~$ psql
psql (10.4 (Ubuntu 10.4-0ubuntu0.18.04))
Type "help" for help.
caseybasichis=>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.