pganalyze / pg_query_go

Go library to parse and normalize SQL queries using the PostgreSQL query parser
BSD 3-Clause "New" or "Revised" License
663 stars 79 forks source link

Vendoring with go mod vendor leads to "fatal error: 'pg_query.h' file not found" #61

Open manitgupta opened 2 years ago

manitgupta commented 2 years ago

Hi,

We are using pg_query_go as a dependency for harbourbridge.

When I vendor in pg_query_go using go mod vendor, I get a missing C header error:

β‡ͺmanitgupta:🏠hb_main/harbourbridge#>go mod vendor
β‡ͺmanitgupta:🏠hb_main/harbourbridge#>make build-static
go build -a -tags osusergo,netgo -ldflags '-w -extldflags "-static"' -o harbourbridge main.go
# github.com/pganalyze/pg_query_go/v2/parser
vendor/github.com/pganalyze/pg_query_go/v2/parser/parser.go:6:10: fatal error: 'pg_query.h' file not found
#include "pg_query.h"
         ^~~~~~~~~~~~
1 error generated.
make: *** [Makefile:6: build-static] Error 2

I am on pg_query_go v2.0.5.

This is what gets vendored in:

β‡ͺmanitgupta:🏠hb_main/harbourbridge#>tree vendor/github.com/pganalyze/pg_query_go/
vendor/github.com/pganalyze/pg_query_go/
└── v2
    β”œβ”€β”€ CHANGELOG.md
    β”œβ”€β”€ go.mod
    β”œβ”€β”€ go.sum
    β”œβ”€β”€ LICENSE
    β”œβ”€β”€ LICENSE.POSTGRESQL
    β”œβ”€β”€ Makefile
    β”œβ”€β”€ makefuncs.go
    β”œβ”€β”€ parser
    β”‚Β Β  β”œβ”€β”€ guc-file.c
    β”‚Β Β  β”œβ”€β”€ parser.go
    β”‚Β Β  β”œβ”€β”€ pg_query.c
    β”‚Β Β  β”œβ”€β”€ pg_query_deparse.c
    β”‚Β Β  β”œβ”€β”€ pg_query_fingerprint.c
    β”‚Β Β  β”œβ”€β”€ pg_query_fingerprint.h
    β”‚Β Β  β”œβ”€β”€ pg_query_internal.h
    β”‚Β Β  β”œβ”€β”€ pg_query_json_plpgsql.c
    β”‚Β Β  β”œβ”€β”€ pg_query_json_plpgsql.h
    β”‚Β Β  β”œβ”€β”€ pg_query_normalize.c
    β”‚Β Β  β”œβ”€β”€ pg_query_outfuncs.h
    β”‚Β Β  β”œβ”€β”€ pg_query_outfuncs_json.c
    β”‚Β Β  β”œβ”€β”€ pg_query_outfuncs_protobuf.c
    β”‚Β Β  β”œβ”€β”€ pg_query_parse.c
    β”‚Β Β  β”œβ”€β”€ pg_query_parse_plpgsql.c
    β”‚Β Β  β”œβ”€β”€ pg_query.pb-c.c
    β”‚Β Β  β”œβ”€β”€ pg_query_readfuncs.h
    β”‚Β Β  β”œβ”€β”€ pg_query_readfuncs_protobuf.c
    β”‚Β Β  β”œβ”€β”€ pg_query_scan.c
    β”‚Β Β  β”œβ”€β”€ pg_query_split.c
    β”‚Β Β  β”œβ”€β”€ protobuf-c.c
    β”‚Β Β  β”œβ”€β”€ src_backend_catalog_namespace.c
    β”‚Β Β  β”œβ”€β”€ src_backend_catalog_pg_proc.c
    β”‚Β Β  β”œβ”€β”€ src_backend_commands_define.c
    β”‚Β Β  β”œβ”€β”€ src_backend_libpq_pqcomm.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_bitmapset.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_copyfuncs.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_equalfuncs.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_extensible.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_list.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_makefuncs.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_nodeFuncs.c
    β”‚Β Β  β”œβ”€β”€ src_backend_nodes_value.c
    β”‚Β Β  β”œβ”€β”€ src_backend_parser_gram.c
    β”‚Β Β  β”œβ”€β”€ src_backend_parser_parse_expr.c
    β”‚Β Β  β”œβ”€β”€ src_backend_parser_parser.c
    β”‚Β Β  β”œβ”€β”€ src_backend_parser_scan.c
    β”‚Β Β  β”œβ”€β”€ src_backend_parser_scansup.c
    β”‚Β Β  β”œβ”€β”€ src_backend_postmaster_postmaster.c
    β”‚Β Β  β”œβ”€β”€ src_backend_storage_ipc_ipc.c
    β”‚Β Β  β”œβ”€β”€ src_backend_storage_lmgr_s_lock.c
    β”‚Β Β  β”œβ”€β”€ src_backend_tcop_postgres.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_adt_datum.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_adt_expandeddatum.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_adt_format_type.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_adt_ruleutils.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_error_assert.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_error_elog.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_fmgr_fmgr.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_hash_dynahash.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_init_globals.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_mb_mbutils.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_misc_guc.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_mmgr_aset.c
    β”‚Β Β  β”œβ”€β”€ src_backend_utils_mmgr_mcxt.c
    β”‚Β Β  β”œβ”€β”€ src_common_encnames.c
    β”‚Β Β  β”œβ”€β”€ src_common_hashfn.c
    β”‚Β Β  β”œβ”€β”€ src_common_keywords.c
    β”‚Β Β  β”œβ”€β”€ src_common_kwlist_d.h
    β”‚Β Β  β”œβ”€β”€ src_common_kwlookup.c
    β”‚Β Β  β”œβ”€β”€ src_common_psprintf.c
    β”‚Β Β  β”œβ”€β”€ src_common_string.c
    β”‚Β Β  β”œβ”€β”€ src_common_stringinfo.c
    β”‚Β Β  β”œβ”€β”€ src_common_wchar.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_comp.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_funcs.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_gram.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_handler.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_reserved_kwlist_d.h
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_scanner.c
    β”‚Β Β  β”œβ”€β”€ src_pl_plpgsql_src_pl_unreserved_kwlist_d.h
    β”‚Β Β  β”œβ”€β”€ src_port_erand48.c
    β”‚Β Β  β”œβ”€β”€ src_port_pg_bitutils.c
    β”‚Β Β  β”œβ”€β”€ src_port_pgsleep.c
    β”‚Β Β  β”œβ”€β”€ src_port_pgstrcasecmp.c
    β”‚Β Β  β”œβ”€β”€ src_port_qsort.c
    β”‚Β Β  β”œβ”€β”€ src_port_random.c
    β”‚Β Β  β”œβ”€β”€ src_port_snprintf.c
    β”‚Β Β  β”œβ”€β”€ src_port_strerror.c
    β”‚Β Β  β”œβ”€β”€ src_port_strnlen.c
    β”‚Β Β  └── xxhash.c
    β”œβ”€β”€ pg_query.go
    β”œβ”€β”€ pg_query.pb.go
    └── README.md

2 directories, 91 files

When I just rm -r vendor, this problem goes away and everything works fine.

I saw a similar issue in another repo here: https://github.com/goccy/go-graphviz/issues/28

Could you please suggest a path to vendoring in this library?

lfittl commented 2 years ago

@manitgupta Unfortunately I'm not sure what is causing this issue - we have seem similar problems ourselves, and are using modvendor to solve them for our own internal use case with the pganalyze collector:

https://github.com/pganalyze/collector/blob/main/Makefile#L32

(possibly you can ask someone internally on the Go team at Google, how go mod vendor should work for .c/.h files?)

manitgupta commented 2 years ago

@lfittl I looked into this issue and the reason seems to be that go mod vendor does not correctly include source files from a directory if there are no .go file present in it. The solution seems to be to include a dummy.go file in the directories. This has been done go-graphviz repo previously and seems to be work. Here is the PR for it: https://github.com/goccy/go-graphviz/pull/37/files

I am willing to do a similar PR for pg_query_go if you'd be willing to review it.

manitgupta commented 2 years ago

This modvendor solution is also interesting. As a workaround, I had earlier written a script in our Makefile to get the source at the needed version for pg_query_go package.

build-vendor:
# vendor the dependencies
    go mod vendor
# git clone the repository and switch to the tag present in harbourbridge's go.mod file (currently: v2.0.5)
    rm -rf vendor/github.com/pganalyze/pg_query_go/v2
    cd vendor/github.com/pganalyze/pg_query_go/ && git clone https://github.com/pganalyze/pg_query_go 
    cd vendor/github.com/pganalyze/pg_query_go/pg_query_go/ && git checkout tags/v2.0.5
    mv vendor/github.com/pganalyze/pg_query_go/pg_query_go/ vendor/github.com/pganalyze/pg_query_go/v2/
# revert to the home directory and build
    go build
graywolf-at-work commented 2 years ago

I've just encountered this as well, upstream ticket is https://github.com/golang/go/issues/26366 ("resolved", yeah, great).