sqlc icon indicating copy to clipboard operation
sqlc copied to clipboard

panic: runtime error: invalid memory address or nil pointer dereference

Open barenko opened this issue 11 months ago • 1 comments

Version

1.27.0

What happened?

docker sqlc generate raise panic when I try to generate the code with a view that contains subquery and cross join on postgres.

I tried wrapper the select but does not works too.

Relevant log output

docker run --rm -v $(pwd):/src -w /src/db sqlc/sqlc generate
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10bf8a7]

goroutine 18 [running]:
github.com/sqlc-dev/sqlc/internal/compiler.(*Compiler).sourceTables(0xc00013c508, 0xc00067b200, {0x1e63060?, 0xc0006789a0?})
        /workspace/internal/compiler/output_columns.go:601 +0xaa7
github.com/sqlc-dev/sqlc/internal/compiler.(*Compiler).outputColumns(0xc00013c508, 0xc00067b200, {0x1e63060, 0xc0006789a0})
        /workspace/internal/compiler/output_columns.go:55 +0x45
github.com/sqlc-dev/sqlc/internal/compiler.(*Compiler).OutputColumns(0xc00013c508, {0x1e63060, 0xc0006789a0})
        /workspace/internal/compiler/output_columns.go:20 +0x71
github.com/sqlc-dev/sqlc/internal/sql/catalog.(*Catalog).createView(0xc000132070, 0xc00067e440, {0x1e633c0?, 0xc00013c508?})
        /workspace/internal/sql/catalog/view.go:9 +0x4e
github.com/sqlc-dev/sqlc/internal/sql/catalog.(*Catalog).Update(0xc000132070, {0x1e62920?}, {0x1e633c0, 0xc00013c508})
        /workspace/internal/sql/catalog/catalog.go:104 +0x2fd
github.com/sqlc-dev/sqlc/internal/compiler.(*Compiler).parseCatalog(0xc00013c508, {0xc0001108a0?, 0xc0001121e6?, 0xa?})
        /workspace/internal/compiler/compile.go:48 +0x2f3
github.com/sqlc-dev/sqlc/internal/compiler.(*Compiler).ParseCatalog(...)
        /workspace/internal/compiler/engine.go:68
github.com/sqlc-dev/sqlc/internal/cmd.parse({_, _}, {_, _}, {_, _}, {{0x0, 0x0}, {0xc0001121e6, 0xa}, ...}, ...)
        /workspace/internal/cmd/generate.go:308 +0x1ae
github.com/sqlc-dev/sqlc/internal/cmd.processQuerySets.func1()
        /workspace/internal/cmd/process.go:107 +0x81a
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:78 +0x56
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 1
        /go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:75 +0x96
error: Recipe `sqlc-generate-raw` failed on line 88 with exit code 2

Database schema

--only one record
create table if not exists settings (
    xpto       decimal not null,
    xpto_alert_perc decimal not null
);

create table if not exists accounts (
    account_id            UUID      default gen_random_uuid() primary key,
    account       VARCHAR(16),
    active BOOLEAN DEFAULT TRUE NOT NULL,
    unique (account)
);

CREATE TABLE IF NOT EXISTS assets (
    asset_id        UUID             DEFAULT gen_random_uuid() PRIMARY KEY,
    type            VARCHAR(16)      NOT NULL,
    subtype         VARCHAR(16)      NOT NULL,
    origin          VARCHAR(32)      NOT NULL,
    asset           VARCHAR(64)      NOT NULL,
    institution     VARCHAR(54)      NULL,
    market_rate     VARCHAR(16)      NULL,
    unit_price      DOUBLE PRECISION NULL,
    matured_at      TIMESTAMP        NULL,
    price_last      DOUBLE PRECISION 
);

create table if not exists allocated_assets(
    allocated_asset_id UUID default gen_random_uuid() primary key,
    asset_id        UUID not null,
    account_id      UUID not null,
    market_position           DOUBLE PRECISION not null                  check (market_position > 0),
    lots                      DOUBLE PRECISION not null,
    invested_amount           DOUBLE PRECISION,
    applicated_at             TIMESTAMP        null,
    lots_available             DOUBLE PRECISION,
    rentability        DOUBLE PRECISION,
    price_avg          DOUBLE PRECISION,
    foreign key (asset_id) references assets (asset_id) on delete cascade,
    foreign key (account_id) references accounts (account_id) on delete cascade
);

create view v_allocated_assets as
select 
    a.asset_id,
    a.type,
    a.subtype,
    a.origin,
    a.asset,
    a.institution,
    a.market_rate,
    a.unit_price,
    a.matured_at,
    a.price_last,
    a.description,
    aa.allocated_asset_id,
    aa.account_id,
    c.account,
    aa.market_position,
    aa.lots,
    CASE
        WHEN a.type = 'stock' THEN
            aa.lots * aa.price_avg
        ELSE
            aa.invested_amount
    END invested_amount,
    aa.applicated_at,
    aa.lots_available,
    CASE
        WHEN a.type = 'stock' THEN
            aa.rentability / 100
        ELSE
            (aa.market_position/aa.invested_amount)-1
    END as current_rentability_perc,
    aa.price_avg,
    CASE 
        WHEN a.matured_at IS NULL OR a.matured_at >= CURRENT_DATE THEN TRUE
        ELSE FALSE
    END AS active,
        CASE 
        WHEN a.matured_at IS NULL THEN NULL                                 
        WHEN a.matured_at < CURRENT_DATE THEN 'VENCIDO'                   
        ELSE (extract(day from (a.matured_at - current_timestamp)))::TEXT 
    END AS valid_for
FROM assets a
inner join allocated_assets aa using (asset_id)
inner join accounts c using(account_id)
ORDER BY
    CASE 
        WHEN a.matured_at >= CURRENT_DATE THEN 1
        WHEN a.matured_at IS NULL THEN 2
        ELSE 3 
    END,
    CASE 
        WHEN a.matured_at >= CURRENT_DATE THEN a.matured_at
        ELSE NULL
    END ASC;

create view v_xpto as
select account_id, account, institution, total_market_position,
	(	select aa.market_position
		from v_allocated_assets aa
		where aa.account_id=account_id and aa.institution = institution and aa.matured_at = next_matured_at
		limit 1
	) as next_matured_value, next_matured_at,
	EXTRACT(day from (next_matured_at-current_timestamp)) as next_matured_in,
	s.xpto * s.xpto_alert_perc - total_market_position as free_to_invest,
	greatest(total_market_position-xpto, 0) as not_covered_by_xpto,
	least(total_market_position, xpto) as covered_by_xpto
from (
	select aa.account_id, aa.account, aa.institution, sum(aa.market_position) total_market_position,
	min(aa.matured_at) as next_matured_at
	from v_allocated_assets aa
	group by account_id, account, institution
)
cross join settings s
order by next_matured_at, institution;

Configuration

version: '2'
plugins:
- name: py
  wasm:
    url: https://downloads.sqlc.dev/plugin/sqlc-gen-python_1.2.0.wasm
    sha256: a6c5d174c407007c3717eea36ff0882744346e6ba991f92f71d6ab2895204c0e
sql:
- schema: "schema.sql"
  queries: "queries.sql"
  engine: postgresql
  codegen:
  - out: ../xpto/model
    plugin: py
    options:
      package: xpto.model
      emit_sync_querier: true
      emit_async_querier: true
      emit_empty_slices: true

What operating system are you using?

Pop!_OS 22.04 LTS x86_64

What database engines are you using?

Postgres 16

What type of code are you generating?

Python code with this command: docker run --rm -v "${PWD}:/src" -w /src/db sqlc/sqlc generate

barenko avatar Jan 20 '25 00:01 barenko

I have also run into this problem. Interestingly, it seems that the version running on play.sqlc.dev correctly identifies the problem: schema.sql:108:2: subquery in FROM must have an alias.

https://play.sqlc.dev/p/782138f97aca4557e70109157edb38a2f5d1d9c1d82c0a8fdf059276ce3116e8

So I guess this bug got introduced somewhere between 1.25.0, and 1.27.0, and I still have the same bug with 1.28.0

angaz avatar Apr 21 '25 16:04 angaz