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 1svcIf-00GQsI-HR for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Oct 2024 12:48:22 +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 1svcIe-00GKqn-0x for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Oct 2024 12:48:20 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1svcId-00GKqf-Nh for pgsql-hackers@lists.postgresql.org; Tue, 01 Oct 2024 12:48:19 +0000 Received: from mail-oa1-x2f.google.com ([2001:4860:4864:20::2f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1svcIZ-0020tc-7H for pgsql-hackers@postgresql.org; Tue, 01 Oct 2024 12:48:18 +0000 Received: by mail-oa1-x2f.google.com with SMTP id 586e51a60fabf-2877d7ae3e5so176763fac.3 for ; Tue, 01 Oct 2024 05:48:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1727786893; x=1728391693; darn=postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=uauawvHhqYHLvL+ryfVUAAJBLN63lNoqoIrO0yYt3JY=; b=SeJ1p7CCLmuvKYG6RTYq6FD7Em3htsBjwCVv4m0uc7pnCGEhBeie8qejBi7RrmltLn WmsZWxtcfLktSpp3qWQxLfbqEyisnWFySkYK9Ke/Lifvr6kQQBGEVgoUSddmVqm+2DAD X4mVhU23ksz8FYiaMhUfbqG47IBMhMqlMgxB0lWusiEGc9b2T/IZ6NZBG9D0/p45AAjD /BqetPKrDc++c241bheWIYTB8C+qOaKilwYylso+p6KO9nEZPdeGDvt+8lwZ9H8Q9w8U OUaElst+XlBaivW5RAOJkyShXyHr5dgy2Oou0Eir/zgV1zyNarZrBSMrBd514RW+MNLk vDrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727786893; x=1728391693; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uauawvHhqYHLvL+ryfVUAAJBLN63lNoqoIrO0yYt3JY=; b=V6dVd1Us3toR8Gu3fWvxcFeWS0MvheCQreIE+/tvAOqPPydkIihwRu48PCgfBV9sw7 L9RdagVxqX4chAlTBJQ4sY0Zu8JzOIRqxCNuLYegIcWZDojR3xLQKCi6AVsN4BGYzan6 HiRwHcmdJKmlMkp2r4xoasZ3D2oGDEmNPQSy2fL74/Tjx11QFW7CXCvHVX3l6tIhT+6C ivTomblwfyw0Nvu19hNNpLpZWxzPQ/MKXFm62gSeoC06mOX7jz937wVaawfhmVbww0bJ /X5TOSZNDHlN30NMIl3IWUDe9+748lmFLcaSy4KmSFQ+FVarql4ZfBqJcjxG56GHqjwE 1JKQ== X-Forwarded-Encrypted: i=1; AJvYcCVyLZddMK/5V7b3RHYIcsYtCkyx8qGxoMFSeoB6+D9U2gJZO0R8MtWTTA7a679xAFQNWNgsah4NAoXduJOg@postgresql.org X-Gm-Message-State: AOJu0YwbPhHKBqKuJgzOxcQyhPEWuGbfbzmhaizT2pUeNh7AOpaDJds6 jwStUIlBBHbX0MGqfGNPG9g3nx73cbUr3NPuOg+Se2C5YCFiPp/O7vo2fB67S18DTFLac1IwuUD zQAewGiwdP6eiehwgra9vCR7gReKRfvDaibLY X-Google-Smtp-Source: AGHT+IHW0wdKdIXgt4BU4ebhWLX3xazbNlxsS4HQBigaZw8L9Orf3/kODSgA78mfyhvd1RzStQMFq6Y+F0k7wahCufU= X-Received: by 2002:a05:6870:3044:b0:261:1f7d:cf70 with SMTP id 586e51a60fabf-28710b9e188mr9059023fac.36.1727786893205; Tue, 01 Oct 2024 05:48:13 -0700 (PDT) MIME-Version: 1.0 References: <20240919.135947.296030969313721973.ishii@postgresql.org> <20240928.194359.1327378331465099656.ishii@postgresql.org> <20240930.090751.1732676018799092095.ishii@postgresql.org> In-Reply-To: <20240930.090751.1732676018799092095.ishii@postgresql.org> From: Jacob Champion Date: Tue, 1 Oct 2024 05:48:02 -0700 Message-ID: Subject: Re: Row pattern recognition To: Tatsuo Ishii Cc: vik@postgresfriends.org, pgsql-hackers@postgresql.org, er@xs4all.nl, peter@eisentraut.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sun, Sep 29, 2024 at 5:08=E2=80=AFPM Tatsuo Ishii = wrote: > > I think implementing MEASURES is challenging. Especially we need to > > find how our parser accepts "colname OVER > > window_definition". Currently PostgreSQL's parser only accepts "func() > > OVER window_definition" Even it is technically possible, I think the > > v1 patch size will become much larger than now due to this. [resending, to the whole list this time] Yeah. In any case, I'm not the right person to bolt MEASURES onto the existing grammar... my misadventures in the PATTERN parser have highlighted how little I know about Bison. :D > Please disregard my proposal. Even if we make such a function, it > would always return NULL for unmatched rows or skipped rows, and I > think the function does not solve your problem. > > However, I wonder if supporting MEASURES solves the problem either > because any columns defined by MEASURES will return NULL except the > first row in a reduced frame. Can you please show an example how to > identify runs of matched rows using MEASURES? I think you're probably right; my suggestion can't distinguish between skipped (but previously matched) rows and entirely-unmatched rows. The test case I'd been working with returned an empty match as a fallback, so it wouldn't have had that problem in practice. I was hoping that one of the existing whole-partition window functions would allow me to cobble something together based on the COUNT(*) measure, but after searching for a while I haven't been able to come up with a solution. Maybe it's just too niche for the window-function version of this -- after all, it only makes sense when using both INITIAL and AFTER MATCH SKIP PAST LAST ROW. A more general solution could identify the row_number of the first and last rows of the window frame, perhaps? But a frame isn't guaranteed to be contiguous, so maybe that doesn't make sense either. Ugh. > I wonder how Oracle solves the problem (an infinite set of possible > matches) without using "--max-rows" or something like that because in > my understanding Oracle supports the regular expressions and PERMUTE. I chose a confusing way to describe it, sorry. The parenthesized language for a pattern can be an infinite set, because A+ could match "( A )" or "( A A )" or "( A A A )" and so on forever. But that doesn't apply to our regex engine in practice; our tables have a finite number of rows, and I *think* the PL for a finite number of rows is also finite, due to the complicated rules on where empty matches are allowed to appear in the language. (In any case, my tool doesn't guard against infinite recursion...) > >> My implementation is really messy -- it leaks memory like a sieve, and > >> I cannibalized the parser from ECPG, which just ended up as an > >> exercise in teaching myself flex/bison. But if there's interest in > >> having this kind of tool in the tree, I can work on making it > >> reviewable. Either way, I should be able to use it to double-check > >> more complicated test cases. > > I definitely am interested in the tool! Okay, good to know! I will need to clean it up considerably, and figure out whether I've duplicated more code than I should have. > >> A while back [2], you were wondering whether our Bison implementation > >> would be able to parse the PATTERN grammar directly. I think this tool > >> proves that the answer is "yes", but PERMUTE in particular causes a > >> shift/reduce conflict. To fix it, I applied the same precedence > >> workaround that we use for CUBE and ROLLUP. > > That's a good news! +1 Thanks, --Jacob