使用go语言的sqlc库时出现’relation “bigint” does not exist’错误。

huangapple go评论66阅读模式
英文:

'relation "bigint" does not exist' error using sqlc library with go

问题

我正在使用sqlc库从SQL查询生成Go代码。

我有一个带有子查询的查询,像这样:

COALESCE(SUM(invoice_payments.total), 0) AS paid,

然后sqlc generate返回以下错误:

# package db
query.sql:101:1: 关系"bigint"不存在

我尝试使用::numeric::int等进行操作转换,但始终得到相同的结果。

还尝试像这样转换为long:

            CAST(SUM(CAST( invoice_payments.total AS LONG)) AS LONG) AS paid,
            SUM(invoice_payments.total::long)::long AS paid,

结果相同。

playground上有完整的示例。

以下是完整示例:

CREATE TABLE clients (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    account_id text NOT NULL,
    CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
    "name" text NOT NULL,
    archived boolean NOT NULL DEFAULT FALSE,
    -- UNIQUE (account_id, name), // what about typos etc balls
    email text NOT NULL,
    phone text NOT NULL DEFAULT '',
    -- UNIQUE (account_id, email),
    -- address
    address_1 text NOT NULL DEFAULT '',
    address_2 text NOT NULL DEFAULT '',
    city text NOT NULL DEFAULT '',
    state_region text NOT NULL DEFAULT '',
    postal_code text NOT NULL DEFAULT '',
    country text NOT NULL DEFAULT '',
    -- currency_code text NOT NULL DEFAULT 'USD',
    -- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code) ON DELETE RESTRICT,
    -- language_code text NOT NULL,
    -- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now(),
    archived_at timestamp
);

CREATE TABLE invoices (
    -- why do we generate the invoice id on the server?
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    account_id text NOT NULL,
    CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
    client_id uuid NOT NULL,
    CONSTRAINT fk_client FOREIGN KEY (client_id) REFERENCES clients (id) ON DELETE CASCADE,
    status text NOT NULL DEFAULT 'draft',
    CONSTRAINT fk_status FOREIGN KEY (status) REFERENCES invoice_statuses (status) ON DELETE RESTRICT,
    archived boolean NOT NULL DEFAULT FALSE,
    heading text NOT NULL DEFAULT 'Invoice',
    NUMBER text NOT NULL,
    UNIQUE (account_id, NUMBER),
    REFERENCE text NOT NULL DEFAULT '',
    issued date NOT NULL,
    due date NOT NULL,
    color text NOT NULL CHECK (LENGTH(color) = 7),
    -- currency_code text NOT NULL DEFAULT 'USD',
    -- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code),
    -- language_code text NOT NULL,
    -- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
    -- items is a list of name, details, price, taxes
    items jsonb NOT NULL DEFAULT '[]' ::jsonb,
    pre_tax_discounts jsonb NOT NULL DEFAULT '[]' ::jsonb,
    -- taxes is a list of name, rate, business number
    taxes jsonb NOT NULL DEFAULT '[]' ::jsonb,
    -- discounts is a list of name, type (rate/fixed), application (pre/post tax), value
    post_tax_discounts jsonb NOT NULL DEFAULT '[]' ::jsonb,
    -- deposits is a list of of name, type (rate/fixed), value
    deposits jsonb NOT NULL DEFAULT '[]' ::jsonb,
    ---- CALCULATED VALUES ---
    -- subtotal is pre-tax, pre-discount
    subtotal numeric NOT NULL DEFAULT 0,
    pre_tax_total numeric NOT NULL DEFAULT 0,
    post_tax_total numeric NOT NULL DEFAULT 0,
    -- INCLUDES pre_tax_total
    grand_total numeric NOT NULL DEFAULT 0,
    deposit_total numeric NOT NULL DEFAULT 0,
    -- current payment total (TODO think about if this is necessary)
    payment numeric NOT NULL DEFAULT 0,
    -- total of deposits - payments OR total - payments
    -- NOTE if an invoice has deposits, then it is a bit of a different creature
    -- or should we call it amount due?
    deposit_due numeric NOT NULL DEFAULT 0,
    balance numeric NOT NULL DEFAULT 0,
    ---- NOTES/TERMS
    notes text NOT NULL DEFAULT '',
    terms text NOT NULL DEFAULT '',
    ---- TIMING ----
    last_sent_at timestamp,
    last_viewed_at timestamp,
    last_paid_at timestamp,
    last_refunded_at timestamp,
    last_deleted_at timestamp,
    archived_at timestamp,
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now()
);

CREATE TABLE invoice_payments (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    invoice_id uuid NOT NULL,
    CONSTRAINT fk_invoice FOREIGN KEY (invoice_id) REFERENCES invoices (id) ON DELETE CASCADE,
    total numeric NOT NULL,
    DATE date NOT NULL,
    method text NOT NULL,
    CONSTRAINT fk_method FOREIGN KEY (method) REFERENCES payment_methods (method) ON DELETE CASCADE,
    notes text NOT NULL DEFAULT '',
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now()
);

---- CLIENTS ----
-- name: SearchClients :many
SELECT
    clients.id,
    -- contact
    clients.name,
    clients.email,
    clients.phone,
    -- address
    clients.address_1,
    clients.address_2,
    clients.city,
    clients.state_region,
    clients.postal_code,
    clients.country,
    -- management
    clients.archived,
    COUNT(invoices.id) AS number_invoices,
    (COALESCE(SUM(invoices.grand_total), 0))::numeric AS owes,
    (COALESCE(SUM(invoices.paid), 0))::numeric AS paid
FROM
    clients
    LEFT JOIN (
        SELECT
            invoices.id,
            invoices.client_id,
            invoices.number,
            invoices.issued,
            invoices.due,
            invoices.status,
            invoices.grand_total,
	  		
	  		-- replacing the paid field definition with this comment works ok
	  		--0 AS paid,
                       COALESCE(SUM(invoice_payments.total), 0) AS paid,
            
	  		-- replacing the overdue field definition with this comment works ok
	  		0 as overdue
	  		--CASE WHEN due < CURRENT_DATE THEN
            --    invoices.grand_total - COALESCE(SUM(invoice_payments.total), 0)
            --ELSE
            --    0
            --END AS overdue
        FROM
            invoices
            LEFT JOIN invoice_payments ON invoices.id = invoice_payments.invoice_id
        GROUP BY
            invoices.id) AS invoices ON clients.id = invoices.client_id
WHERE
    clients.account_id = @account_id
    AND clients.archived = ANY (@archived::boolean[])
    AND (clients.name ILIKE '%' || @query || '%'
        OR invoices.number ILIKE '%' || @query || '%')
GROUP BY
    clients.id
ORDER BY
    clients.name ASC,
    clients.updated_at DESC;
英文:

I'm using the sqlc library to generate go code from SQL queries.

I have a query with a subquery like this:

COALESCE(SUM(invoice_payments.total), 0) AS paid,

And sqlc generate returns the following error:

# package db
query.sql:101:1: relation &quot;bigint&quot; does not exist

I tried casting the operation with ::numeric, ::int, etc, and always receive the same result

Also tried to cast to long like this:

            CAST(SUM(CAST( invoice_payments.total AS LONG)) AS LONG) AS paid,
            SUM(invoice_payments.total::long)::long AS paid,

with the same results

playground with complete example

full example below

CREATE TABLE clients (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    account_id text NOT NULL,
    CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
    &quot;name&quot; text NOT NULL,
    archived boolean NOT NULL DEFAULT FALSE,
    -- UNIQUE (account_id, name), // what about typos etc balls
    email text NOT NULL,
    phone text NOT NULL DEFAULT &#39;&#39;,
    -- UNIQUE (account_id, email),
    -- address
    address_1 text NOT NULL DEFAULT &#39;&#39;,
    address_2 text NOT NULL DEFAULT &#39;&#39;,
    city text NOT NULL DEFAULT &#39;&#39;,
    state_region text NOT NULL DEFAULT &#39;&#39;,
    postal_code text NOT NULL DEFAULT &#39;&#39;,
    country text NOT NULL DEFAULT &#39;&#39;,
    -- currency_code text NOT NULL DEFAULT &#39;USD&#39;,
    -- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code) ON DELETE RESTRICT,
    -- language_code text NOT NULL,
    -- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now(),
    archived_at timestamp
);

CREATE TABLE invoices (
    -- why do we generate the invoice id on the server?
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    account_id text NOT NULL,
    CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
    client_id uuid NOT NULL,
    CONSTRAINT fk_client FOREIGN KEY (client_id) REFERENCES clients (id) ON DELETE CASCADE,
    status text NOT NULL DEFAULT &#39;draft&#39;,
    CONSTRAINT fk_status FOREIGN KEY (status) REFERENCES invoice_statuses (status) ON DELETE RESTRICT,
    archived boolean NOT NULL DEFAULT FALSE,
    heading text NOT NULL DEFAULT &#39;Invoice&#39;,
    NUMBER text NOT NULL,
    UNIQUE (account_id, NUMBER),
    REFERENCE text NOT NULL DEFAULT &#39;&#39;,
    issued date NOT NULL,
    due date NOT NULL,
    color text NOT NULL CHECK (LENGTH(color) = 7),
    -- currency_code text NOT NULL DEFAULT &#39;USD&#39;,
    -- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code),
    -- language_code text NOT NULL,
    -- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
    -- items is a list of name, details, price, taxes
    items jsonb NOT NULL DEFAULT &#39;[]&#39; ::jsonb,
    pre_tax_discounts jsonb NOT NULL DEFAULT &#39;[]&#39; ::jsonb,
    -- taxes is a list of name, rate, business number
    taxes jsonb NOT NULL DEFAULT &#39;[]&#39; ::jsonb,
    -- discounts is a list of name, type (rate/fixed), application (pre/post tax), value
    post_tax_discounts jsonb NOT NULL DEFAULT &#39;[]&#39; ::jsonb,
    -- deposits is a list of of name, type (rate/fixed), value
    deposits jsonb NOT NULL DEFAULT &#39;[]&#39; ::jsonb,
    ---- CALCULATED VALUES ---
    -- subtotal is pre-tax, pre-discount
    subtotal numeric NOT NULL DEFAULT 0,
    pre_tax_total numeric NOT NULL DEFAULT 0,
    post_tax_total numeric NOT NULL DEFAULT 0,
    -- INCLUDES pre_tax_total
    grand_total numeric NOT NULL DEFAULT 0,
    deposit_total numeric NOT NULL DEFAULT 0,
    -- current payment total (TODO think about if this is necessary)
    payment numeric NOT NULL DEFAULT 0,
    -- total of deposits - payments OR total - payments
    -- NOTE if an invoice has deposits, then it is a bit of a different creature
    -- or should we call it amount due?
    deposit_due numeric NOT NULL DEFAULT 0,
    balance numeric NOT NULL DEFAULT 0,
    ---- NOTES/TERMS
    notes text NOT NULL DEFAULT &#39;&#39;,
    terms text NOT NULL DEFAULT &#39;&#39;,
    ---- TIMING ----
    last_sent_at timestamp,
    last_viewed_at timestamp,
    last_paid_at timestamp,
    last_refunded_at timestamp,
    last_deleted_at timestamp,
    archived_at timestamp,
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now()
);

CREATE TABLE invoice_payments (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
    invoice_id uuid NOT NULL,
    CONSTRAINT fk_invoice FOREIGN KEY (invoice_id) REFERENCES invoices (id) ON DELETE CASCADE,
    total numeric NOT NULL,
    DATE date NOT NULL,
    method text NOT NULL,
    CONSTRAINT fk_method FOREIGN KEY (method) REFERENCES payment_methods (method) ON DELETE CASCADE,
    notes text NOT NULL DEFAULT &#39;&#39;,
    created_at timestamp NOT NULL DEFAULT now(),
    updated_at timestamp NOT NULL DEFAULT now()
);

---- CLIENTS ----
-- name: SearchClients :many
SELECT
    clients.id,
    -- contact
    clients.name,
    clients.email,
    clients.phone,
    -- address
    clients.address_1,
    clients.address_2,
    clients.city,
    clients.state_region,
    clients.postal_code,
    clients.country,
    -- management
    clients.archived,
    COUNT(invoices.id) AS number_invoices,
    (COALESCE(SUM(invoices.grand_total), 0))::numeric AS owes,
    (COALESCE(SUM(invoices.paid), 0))::numeric AS paid
FROM
    clients
    LEFT JOIN (
        SELECT
            invoices.id,
            invoices.client_id,
            invoices.number,
            invoices.issued,
            invoices.due,
            invoices.status,
            invoices.grand_total,
	  		
	  		-- replacing the paid field definition with this comment works ok
	  		--0 AS paid,
                       COALESCE(SUM(invoice_payments.total), 0) AS paid,
            
	  		-- replacing the overdue field definition with this comment works ok
	  		0 as overdue
	  		--CASE WHEN due &lt; CURRENT_DATE THEN
            --    invoices.grand_total - COALESCE(SUM(invoice_payments.total), 0)
            --ELSE
            --    0
            --END AS overdue
        FROM
            invoices
            LEFT JOIN invoice_payments ON invoices.id = invoice_payments.invoice_id
        GROUP BY
            invoices.id) AS invoices ON clients.id = invoices.client_id
WHERE
    clients.account_id = @account_id
    AND clients.archived = ANY (@archived::boolean[])
    AND (clients.name ILIKE &#39;%&#39; || @query || &#39;%&#39;
        OR invoices.number ILIKE &#39;%&#39; || @query || &#39;%&#39;)
GROUP BY
    clients.id
ORDER BY
    clients.name ASC,
    clients.updated_at DESC;

答案1

得分: 1

原因是您的值太长,无法转换为数字或整数(不适合),请尝试将numeric or int替换为long

英文:

The reason is your value is too long to be casted to numeric or int (doesn't fit) try replacing numeric or int to long

huangapple
  • 本文由 发表于 2021年7月15日 08:16:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/68386429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定