Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1euyrq-0004eP-8U for pgsql-hackers@arkaria.postgresql.org; Sun, 11 Mar 2018 11:10:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1euyro-0002wx-Fp for pgsql-hackers@arkaria.postgresql.org; Sun, 11 Mar 2018 11:10:16 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1euyro-0002wk-8W for pgsql-hackers@lists.postgresql.org; Sun, 11 Mar 2018 11:10:16 +0000 Received: from mail-lf0-x229.google.com ([2a00:1450:4010:c07::229]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1euyrf-0006GV-73 for pgsql-hackers@postgresql.org; Sun, 11 Mar 2018 11:10:15 +0000 Received: by mail-lf0-x229.google.com with SMTP id v9-v6so19059409lfa.11 for ; Sun, 11 Mar 2018 04:10:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=I+40zAVVpQt/AJeyeWIYRTRYEf1iZanuyHWT3lib6uk=; b=k3VrRZz5zFqVY3ITI2YwibmNFAatyhrsO9sklHnLTh9N0XGucQtK++t/Xvg29Ub4BM 8F4pORZuGJFyB61EfsJZpqmty9AqGFgiF/vUK/JOCT/DIlulg1b50MRAin/IPc5uWvzF QYNqFAGoF4W+O7Fu1+3ukUm96qzMKyfEmpqRJ50SQAR9SA5gTZPmgfmwIQsIL1+2HvGS kA/SqNOR87VXeZUwBnj6BhwTB2EDOaj7wzON/q2OZWrQgZGUqrxO+Y5UxOaTxw9DUP+1 pqav2XozRjMhLzikonom7ToxZF5Enqj8lIUxWogdMObyrFy4QswwR2eVS58z2nOnrA8I l6Jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=I+40zAVVpQt/AJeyeWIYRTRYEf1iZanuyHWT3lib6uk=; b=amKqcle51JIjgf8RLPGO5z0A+uMIpjulkEsUarIrBtPhBh5hUKS5bpJUoGbT6ixuXK 51nTS/2RYDy3tQA75MMcOATZb6rBBx8EO+MZd5MOrMSOS7xr6ysRq+ZntCebRLL+zr4t iUKEB8x1VF7pI9ShT7Wknn0+HAD4AbTSKEy4JeMIhHTdIRf8YjVA+xrgfym2elpW+2AV EvpLF/Ym8FBZayZGyk+aE2sUTvbWV7oY9Z+etv9KnmtVbDLAWpnfubwNEDSc1/Ij4bmM 61lsj0xPD3JCYbmFU9li17sZ7c4Hm5/+OCXbCvMYTB2HOd9ONP6RFPE1p28f9FZFuXdy H/fw== X-Gm-Message-State: AElRT7F9fVWwJjZrzpq8nlvP99zagXGN/vWIWl15q2Pp55eNi5ktuRr9 K44iDLqBzUZRZCqBKXTUCQqfus1bsI4IrrGzzC+mXWnPn5+ZLTdhC8el0Izwppocqmjld5MZ2P9 sL/LsQ/6G1gz2JcNE3104m4rqE7iJVd1MJtmN/mbBfiYnCJwFOLC8sOa1enqZDBIepdFZ98KMKt Ik+zaSUU/w70A= X-Google-Smtp-Source: AG47ELvl2DsBlIbWQC+wVRp0+mlQ15qGdzYPpVZ3abT3cjpCsexR4gMa/g87uz0VAy6jWYvHDZBaMA== X-Received: by 10.46.48.10 with SMTP id w10mr2741004ljw.76.1520766603816; Sun, 11 Mar 2018 04:10:03 -0700 (PDT) Received: from [10.137.2.17] (178-78-220-132.customers.ownit.se. [178.78.220.132]) by smtp.gmail.com with ESMTPSA id h23-v6sm1150564lfj.87.2018.03.11.04.10.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Mar 2018 04:10:02 -0700 (PDT) Subject: Re: Parallel Aggregates for string_agg and array_agg To: David Rowley Cc: Andres Freund , PostgreSQL-development References: <20180301212631.kede4nyuttzxwoxq@alap3.anarazel.de> <24abe018-b3c6-2117-b5b9-39e660db00bd@2ndquadrant.com> From: Tomas Vondra Message-ID: <1b6ee15c-c218-761e-0120-c1ed438e2db2@2ndquadrant.com> Date: Sun, 11 Mar 2018 12:10:00 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 03/11/2018 07:31 AM, David Rowley wrote: > On 11 March 2018 at 12:11, Tomas Vondra wrote: >> On 03/05/2018 04:51 AM, David Rowley wrote: >>> On 5 March 2018 at 04:54, Tomas Vondra wrote: >>> Consider the following slightly backward-looking case; >>> >>> select string_agg(',', x::text) from generate_Series(1,10)x; >>> string_agg >>> ---------------------- >>> ,2,3,4,5,6,7,8,9,10, >>> >>> Here the delimiter is the number, not the ','. Of course, the >>> delimiter for the first aggregated result is not shown. The previous >>> implementation of the transfn for this aggregate just threw away the >>> first delimiter, but that's no good for parallel aggregates as the >>> transfn may be getting called in a parallel worker, in which case >>> we'll need that delimiter in the combine function to properly join to >>> the other partial aggregated results matching the same group. >>> >> >> Hmmm, you're right I haven't considered the delimiter might be variable. >> But isn't just yet another hint that while StringInfo was suitable for >> aggregate state of non-parallel string_agg, it may not be for the >> parallel version? >> >> What if the parallel string_agg instead used something like this: >> >> struct StringAggState >> { >> char *delimiter; /* first delimiter */ >> StringInfoData str; /* partial aggregate state */ >> } StringAggState; >> >> I think that would make the code cleaner, compared to using the cursor >> field for that purpose. But maybe it'd make it not possible to share >> code with the non-parallel aggregate, not sure. > > It would be possible to use something like that. The final function > would just need to take 'str' and ignore 'delimiter', whereas the > combine function would need both. However, you could optimize the > above to just have a single StringInfoData and have a pointer to the > start of the actual data (beyond the first delimiter), that would save > us a call to palloc and also allow the state's data to exist in one > contiguous block of memory, which will be more cache friendly when it > comes to reading it back again. The pointer here would, of course, > have to be an offset into the data array, since repallocs would cause > problems as the state grew. > > This is kinda the option I was going for with using the cursor. I > didn't think that was going to be a problem. It seems that cursor was > invented so that users of StringInfo could store a marker somehow > along with the string. The comment for cursor read: > > * cursor is initialized to zero by makeStringInfo or initStringInfo, > * but is not otherwise touched by the stringinfo.c routines. > * Some routines use it to scan through a StringInfo. > > The use of the cursor field does not interfere with pqformat.c's use > of it as in the serialization functions we're creating a new > StringInfo for the 'result'. If anything tries to send the internal > state, then that's certainly broken. It needs to be serialized before > that can happen. > > I don't quite see how inventing a new struct would make the code > cleaner. It would make the serialization and deserialization functions > have to write and read more fields for the lengths of the data > contained in the state. > > I understand that the cursor field is used in pqformat.c quite a bit, > but I don't quite understand why it should get to use that field the > way it wants, but the serialization and deserialization functions > shouldn't. I'd understand that if we were trying to phase out the > cursor field from StringInfoData, but I can't imagine that's going to > happen. > > Of course, with that all said. If you really strongly object to how > I've done this, then I'll change it to use a new struct type. I had > just tried to make the patch footprint as small as possible, and the > above text is me just explaining my reasoning behind this, not me > objecting to your request for me to change it. Let me know your > thoughts after reading the above. > Hmmm, I guess you're right, I didn't really thought that through. I don't object to sticking to the current approach. > In the meantime, I've attached an updated patch. The only change it > contains is updating the "Partial Mode" column in the docs from "No" > to "Yes". > Yeah, seems fine to me. I wonder what else would be needed before switching the patch to RFC. I plan to do that after a bit more testing sometime early next week, unless someone objects. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services