Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1thP6p-0022IZ-RK for pgsql-bugs@arkaria.postgresql.org; Mon, 10 Feb 2025 08:25:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1thP6o-003n8A-HZ for pgsql-bugs@arkaria.postgresql.org; Mon, 10 Feb 2025 08:25:38 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1thP6o-003n82-3t for pgsql-bugs@lists.postgresql.org; Mon, 10 Feb 2025 08:25:38 +0000 Received: from mail.postgrespro.ru ([93.174.131.139]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1thP6k-004IEp-1T for pgsql-bugs@lists.postgresql.org; Mon, 10 Feb 2025 08:25:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1739175931; bh=xdlZ34HnoePVmGIqvb1oJcBbTfNzeRyPsxuNRSOdqj4=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Message-ID:From; b=E/4uD7xEt+he26lwHyoLDIvyJRajx5mOVTTcw2LFI6C+NI+ZIlpYivLIkH3e67Op4 esZ2beqGZl0HeA4THKwwMfEyt033lWDjT2/AujJLGac9a+Vsjt7yweSa+W6rJQQvvF NlAf7adiMUGG0wyojJ0Al+NwiwasqJSgVcfo6CT5/cckGlrOuVFYiG7fN2ZbV2e2WP 2o6cYpV25b5plXj/VpiQOTddbIfsh5d5cltNdezth/2Nr/kWWtAN5FnkrJmo2evihb tHXHwnPYgH7QJ/hhFuQq/NI5sryXyMrR+7fDhOxUj3VrgkCSRs6jhBJ9wCZJYo+Tmy sHW7O9yO2/wLg== Received: from mail.postgrespro.ru (webmail-master-mstn.l.postgrespro.ru [192.168.2.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: v.popolitov@postgrespro.ru) by mail.postgrespro.ru (Postfix/587) with ESMTPSA id 176B360938; Mon, 10 Feb 2025 11:25:31 +0300 (MSK) MIME-Version: 1.0 Date: Mon, 10 Feb 2025 15:25:31 +0700 From: Vladlen Popolitov To: foxido@foxido.dev, pgsql-bugs@lists.postgresql.org Cc: PG Bug reporting form Subject: Re: BUG #18801: JIT recompiles function for each row if custom aggregation function is used In-Reply-To: <18801-8657563d6f52110b@postgresql.org> References: <18801-8657563d6f52110b@postgresql.org> Message-ID: <412edff1cf1d62399e49f5ab94e88913@postgrespro.ru> X-Sender: v.popolitov@postgrespro.ru Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-KSMG-AntiPhishing: NotDetected X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.1.0.7854, bases: 2025/02/10 05:33:00 #27152708 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk PG Bug reporting form писал(а) 2025-02-10 00:46: Hi, From my point of view, it works as it was asked: you wrote query, that call function for every row of the table, this function has 1 select statement, you set GUCs to compile every SELECT to jit and store compile result to the file. As result you have 10000 files for tables with 10000 rows. If you write the same function without SELECT statement (change to IF ELSE ENDIF), you would not have 10000 files: no query, no jit. If you include 2 SELECTs into the function, you would have 20000 files. What is wrong in this behaviour? If you expect to have only 1 compilation for exactly the same (or similar) queries, it does not exist in the moment. I am working with jit cache now, it would help, if SELECT query is stored in plan cache (it is used for queries in plpgsql, not SQL language functions). > The following bug has been logged on the website: > > Bug reference: 18801 > Logged by: Ilya Gladyshev > Email address: foxido@foxido.dev > PostgreSQL version: 17.2 > Operating system: arch linux > Description: > > Hi! I've noticed that for custom aggregation function jit (re)compiles > same > code for every row. > > Consider this code sample: > ``` > create table test(a float, b float); > insert into test select a, a % 10 from generate_series(1, 10000) a; > > create function custom_max(float8, float8) returns float8 as > $$ > select case when $1 > $2 then $1 else $2 end > $$ > language sql; > > create aggregate custom_agg_max(float8) > ( > sfunc = custom_max, > stype = float8, > initcond = 0 > ); > > set jit = on; > set jit_above_cost = 0; > set jit_dump_bitcode = on; > explain analyze select custom_agg_max(a) from > test; > ``` > > This query runs ~8 seconds ([1]) and generates 10001 llvm bytecode > files in > data directory. For comparison, built-in `select max(a) from test` runs > ~50ms and generates 2 bytecode files. > > And all bytecode files are same, with only difference between them is > function names [2]. > > What i tested so far: > — bug disappears if sfunc in aggregate is built-in (for example if > custom_agg is [3]) > — bug still present if function is marked as pure as possible (parallel > safe, leakproof, immutable, etc), but even for inpure functions jit > shouldn't recompile for each row > > Also notice that JIT runtime counters are incorrect, actually ~90% time > is > spent inside llvm (FPPass), according to perf. > > Bug is present on 17.2 and master (9926f85) > > [1] > ``` > QUERY PLAN > > ------------------------------------------------------------------------------------------------------------------------------ > Aggregate (cost=2655.00..2655.01 rows=1 width=8) (actual > time=8154.805..8154.806 rows=1 loops=1) > Buffers: shared hit=69 > -> Seq Scan on test (cost=0.00..155.00 rows=10000 width=8) (actual > time=0.033..3.371 rows=10000 loops=1) > Buffers: shared hit=55 > Planning: > Buffers: shared hit=23 > Planning Time: 0.240 ms > JIT: > Functions: 3 > Options: Inlining false, Optimization false, Expressions true, > Deforming > true > Timing: Generation 0.193 ms (Deform 0.056 ms), Inlining 0.000 ms, > Optimization 0.175 ms, Emission 3.290 ms, Total 3.658 ms > Execution Time: 8172.018 ms > (12 rows) > ``` > > [2] > ``` > < ; ModuleID = '397491.986.bc' > --- >> ; ModuleID = '397491.611.bc' > 15c15 > < define noundef i64 @evalexpr_986_0(ptr nocapture noundef writeonly > %0, ptr > %1, ptr %2) #0 { > --- >> define noundef i64 @evalexpr_611_0(ptr nocapture noundef writeonly %0, >> ptr > %1, ptr %2) #0 { > ``` > > [3] > ``` > CREATE AGGREGATE custom_agg_avg (float8) > ( > sfunc = float8_accum, > stype = float8[], > finalfunc = float8_avg, > initcond = '{0,0,0}' > ); > ``` -- Best regards, Vladlen Popolitov.