Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iZL4U-0003tu-50 for pgsql-hackers@arkaria.postgresql.org; Mon, 25 Nov 2019 20:34:58 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iZL4S-0001x2-MJ for pgsql-hackers@arkaria.postgresql.org; Mon, 25 Nov 2019 20:34:56 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iZL4S-0001wo-9t for pgsql-hackers@lists.postgresql.org; Mon, 25 Nov 2019 20:34:56 +0000 Received: from mail-qv1-xf42.google.com ([2607:f8b0:4864:20::f42]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1iZL4P-00026W-F7 for pgsql-hackers@postgresql.org; Mon, 25 Nov 2019 20:34:55 +0000 Received: by mail-qv1-xf42.google.com with SMTP id x14so6361456qvu.0 for ; Mon, 25 Nov 2019 12:34:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=Cauhvr9TGsyG1P0OMBvWJiU/fAApel24LZy8lXkrlwM=; b=U0H0oLS3oUI5Lsk9AOku51Vo4rDJ2Vl5FMElMoePCzW6YWMSJalOcwF10wYXTD1bxY VRODZ+hEGmnE0435x4c7f/47O5zHubrrANlrR4lBNiQ7IyPnqONpCG9H01cfbDdt+cez pptOs9pHtBix0UyxRfWm2kO3pk38fSDkODI8Owo8i5IyTv5Nf1CoeO+WnGOJNn/3FacJ aMCNR64h1ngfyOBLFc9/6Z57NGJMCkzekI95r65mokW/t3x17cn2i9QPKr1kJ2dvNqzF JODhytAJrEol6ri8lUblmj6awaE64QJ6T+OrRUjaoWnQwj5OjJdWw3CqfK2aJ3mg5LML eVkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=Cauhvr9TGsyG1P0OMBvWJiU/fAApel24LZy8lXkrlwM=; b=OGY8yvgsUaqLFaaNskwsI5RnTTZujFV7bbErrgWsjmZkqAfZw3GOfkwrinp9y03MJZ je9hMcAb4GnGTPB0hY7+n8Cpv1hmaqHpyzUEgK9xUPgg9NWg4ZcrXiTspCC8Vm8D7q8U OSUYaz9g2L4Tn7oekUobgFbvaCSaCe4thX9TX3x2/FqBzJFW8T+Ysgzu7ul9JUmInJeS KzFjjQ8hVOsbv1VPvdcECjBC7QG45EXvm4gX71sTy61xsoNlLAswJeraMdMdW9iA7IUQ HYt3DwIsJhumqUkL82gRUN2EvXFSt2PQ/yWm4LCLNHwcBSfXOsNzIWoKc3DCF/5q2V3p WDjA== X-Gm-Message-State: APjAAAWBTovrDkAIjwcgBPcE2vsmCqZqCfDavrz9Q5Lh27m4Zw1VvATo JyXSD2BWpP0jjqgiYk4qhs8raw== X-Google-Smtp-Source: APXvYqxzJkfBDW/7ZsfQ6NEuzOLjFWtmj38kr/I+fHx3/WLN8pO+SpE03Ibxjon3gkADjGQtrU50hw== X-Received: by 2002:a0c:ea2d:: with SMTP id t13mr13109901qvp.46.1574714092350; Mon, 25 Nov 2019 12:34:52 -0800 (PST) Received: from nimloth.alvh.no-ip.org ([190.121.29.3]) by smtp.gmail.com with ESMTPSA id f7sm3931915qkb.79.2019.11.25.12.34.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2019 12:34:51 -0800 (PST) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 4667A300AB1; Mon, 25 Nov 2019 17:34:42 -0300 (-03) Date: Mon, 25 Nov 2019 17:34:42 -0300 From: Alvaro Herrera To: Tomas Vondra Cc: Surafel Temesgen , PostgreSQL Hackers , Andrew Gierth Subject: Re: FETCH FIRST clause WITH TIES option Message-ID: <20191125203442.GA30191@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="X1bOJ3K7DJ5YkBrT" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20191111145649.GA7829@alvherre.pgsql> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2019-Nov-11, Alvaro Herrera wrote: > I'm not sure the proposed changes to gram.y are all that great, though. Here's a proposed simplification of the gram.y changes. There are two things here: 1. cosmetic: we don't need the LimitClause struct; we can use just SelectLimit, and return that from limit_clause; that can be complemented using the offset_clause if there's any at select_limit level. 2. there's a gratuituous palloc() in opt_select_limit when there's no clause, that seems to be there just so that NULLs can be returned. That's one extra palloc for SELECTs parsed using one the affected productions ... it's not every single select, but it seems bad enough it's worth fixing. I fixed #2 by just checking whether the return from opt_select_limit is NULL. ISTM it'd be better to pass the SelectLimit pointer to insertSelectOptions instead (which is a static function in gram.y anyway so there's no difficulty there). -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services --X1bOJ3K7DJ5YkBrT Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="with_ties_gram.patch" diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index e776215155..f4304a45b9 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -135,13 +135,6 @@ typedef struct SelectLimit LimitOption limitOption; } SelectLimit; -/* Private struct for the result of limit_clause production */ -typedef struct LimitClause -{ - Node *limitCount; - LimitOption limitOption; -} LimitClause; - /* ConstraintAttributeSpec yields an integer bitmask of these flags: */ #define CAS_NOT_DEFERRABLE 0x01 #define CAS_DEFERRABLE 0x02 @@ -258,8 +251,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionSpec *partspec; PartitionBoundSpec *partboundspec; RoleSpec *rolespec; - struct SelectLimit *SelectLimit; - struct LimitClause *LimitClause; + struct SelectLimit *selectlimit; } %type stmt schema_stmt @@ -392,8 +384,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type import_qualification_type %type import_qualification %type vacuum_relation -%type opt_select_limit select_limit -%type limit_clause +%type opt_select_limit select_limit limit_clause %type stmtblock stmtmulti OptTableElementList TableElementList OptInherit definition @@ -11343,8 +11334,9 @@ select_no_parens: | select_clause opt_sort_clause for_locking_clause opt_select_limit { insertSelectOptions((SelectStmt *) $1, $2, $3, - ($4)->limitOffset, ($4)->limitCount, - ($4)->limitOption, + ($4) ? ($4)->limitOffset : NULL, + ($4) ? ($4)->limitCount : NULL, + ($4) ? ($4)->limitOption : LIMIT_OPTION_DEFAULT, NULL, yyscanner); $$ = $1; @@ -11362,7 +11354,7 @@ select_no_parens: { insertSelectOptions((SelectStmt *) $2, NULL, NIL, NULL, NULL, - LIMIT_OPTION_DEFAULT,$1, + LIMIT_OPTION_DEFAULT, $1, yyscanner); $$ = $2; } @@ -11370,15 +11362,16 @@ select_no_parens: { insertSelectOptions((SelectStmt *) $2, $3, NIL, NULL, NULL, - LIMIT_OPTION_DEFAULT,$1, + LIMIT_OPTION_DEFAULT, $1, yyscanner); $$ = $2; } | with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit { insertSelectOptions((SelectStmt *) $2, $3, $4, - ($5)->limitOffset, ($5)->limitCount, - ($5)->limitOption, + ($5) ? ($5)->limitOffset : NULL, + ($5) ? ($5)->limitCount : NULL, + ($5) ? ($5)->limitOption : LIMIT_OPTION_DEFAULT, $1, yyscanner); $$ = $2; @@ -11683,27 +11676,17 @@ sortby: a_expr USING qual_all_Op opt_nulls_order select_limit: limit_clause offset_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); - n->limitOffset = $2; - n->limitCount = ($1)->limitCount; - n->limitOption = ($1)->limitOption; - $$ = n; + $$ = $1; + ($$)->limitOffset = $2; } | offset_clause limit_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); - n->limitOffset = $1; - n->limitCount = ($2)->limitCount; - n->limitOption = ($2)->limitOption; - $$ = n; + $$ = $2; + ($$)->limitOffset = $1; } | limit_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); - n->limitOffset = NULL; - n->limitCount = ($1)->limitCount; - n->limitOption = ($1)->limitOption; - $$ = n; + $$ = $1; } | offset_clause { @@ -11717,20 +11700,14 @@ select_limit: opt_select_limit: select_limit { $$ = $1; } - | /* EMPTY */ - { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); - n->limitOffset = NULL; - n->limitCount = NULL; - n->limitOption = LIMIT_OPTION_DEFAULT; - $$ = n; - } + | /* EMPTY */ { $$ = NULL; } ; limit_clause: LIMIT select_limit_value { - LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause)); + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + n->limitOffset = NULL; n->limitCount = $2; n->limitOption = LIMIT_OPTION_COUNT; $$ = n; @@ -11753,21 +11730,24 @@ limit_clause: */ | FETCH first_or_next select_fetch_first_value row_or_rows ONLY { - LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause)); + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + n->limitOffset = NULL; n->limitCount = $3; n->limitOption = LIMIT_OPTION_COUNT; $$ = n; } | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES { - LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause)); + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + n->limitOffset = NULL; n->limitCount = $3; n->limitOption = LIMIT_OPTION_WITH_TIES; $$ = n; } | FETCH first_or_next row_or_rows ONLY { - LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause)); + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); n->limitOption = LIMIT_OPTION_COUNT; $$ = n; --X1bOJ3K7DJ5YkBrT--