1997-11-25 23:07:18 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* parse_node.h
|
2003-04-30 00:13:11 +02:00
|
|
|
* Internal definitions for parser
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*
|
2020-01-01 18:21:45 +01:00
|
|
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/parser/parse_node.h
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef PARSE_NODE_H
|
|
|
|
#define PARSE_NODE_H
|
|
|
|
|
1999-07-16 01:04:24 +02:00
|
|
|
#include "nodes/parsenodes.h"
|
2017-04-01 06:17:18 +02:00
|
|
|
#include "utils/queryenvironment.h"
|
2008-06-19 02:46:06 +02:00
|
|
|
#include "utils/relcache.h"
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2009-10-31 02:41:31 +01:00
|
|
|
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
/* Forward references for some structs declared below */
|
|
|
|
typedef struct ParseState ParseState;
|
|
|
|
typedef struct ParseNamespaceItem ParseNamespaceItem;
|
|
|
|
typedef struct ParseNamespaceColumn ParseNamespaceColumn;
|
|
|
|
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
/*
|
|
|
|
* Expression kinds distinguished by transformExpr(). Many of these are not
|
|
|
|
* semantically distinct so far as expression transformation goes; rather,
|
|
|
|
* we distinguish them so that context-specific error messages can be printed.
|
|
|
|
*
|
|
|
|
* Note: EXPR_KIND_OTHER is not used in the core code, but is left for use
|
|
|
|
* by extension code that might need to call transformExpr(). The core code
|
|
|
|
* will not enforce any context-driven restrictions on EXPR_KIND_OTHER
|
|
|
|
* expressions, so the caller would have to check for sub-selects, aggregates,
|
2016-09-13 19:54:24 +02:00
|
|
|
* window functions, SRFs, etc if those need to be disallowed.
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
*/
|
|
|
|
typedef enum ParseExprKind
|
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
EXPR_KIND_NONE = 0, /* "not in an expression" */
|
|
|
|
EXPR_KIND_OTHER, /* reserved for extensions */
|
|
|
|
EXPR_KIND_JOIN_ON, /* JOIN ON */
|
|
|
|
EXPR_KIND_JOIN_USING, /* JOIN USING */
|
|
|
|
EXPR_KIND_FROM_SUBSELECT, /* sub-SELECT in FROM clause */
|
|
|
|
EXPR_KIND_FROM_FUNCTION, /* function in FROM clause */
|
|
|
|
EXPR_KIND_WHERE, /* WHERE */
|
|
|
|
EXPR_KIND_HAVING, /* HAVING */
|
2013-07-17 02:15:36 +02:00
|
|
|
EXPR_KIND_FILTER, /* FILTER */
|
2013-05-29 22:58:43 +02:00
|
|
|
EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */
|
|
|
|
EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
EXPR_KIND_WINDOW_FRAME_GROUPS, /* window frame clause with GROUPS */
|
2013-05-29 22:58:43 +02:00
|
|
|
EXPR_KIND_SELECT_TARGET, /* SELECT target list item */
|
|
|
|
EXPR_KIND_INSERT_TARGET, /* INSERT target list item */
|
|
|
|
EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */
|
|
|
|
EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */
|
|
|
|
EXPR_KIND_GROUP_BY, /* GROUP BY */
|
|
|
|
EXPR_KIND_ORDER_BY, /* ORDER BY */
|
|
|
|
EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */
|
|
|
|
EXPR_KIND_LIMIT, /* LIMIT */
|
|
|
|
EXPR_KIND_OFFSET, /* OFFSET */
|
|
|
|
EXPR_KIND_RETURNING, /* RETURNING */
|
|
|
|
EXPR_KIND_VALUES, /* VALUES */
|
2017-01-16 21:23:11 +01:00
|
|
|
EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */
|
2013-05-29 22:58:43 +02:00
|
|
|
EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */
|
|
|
|
EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */
|
|
|
|
EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */
|
|
|
|
EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */
|
|
|
|
EXPR_KIND_INDEX_EXPRESSION, /* index expression */
|
|
|
|
EXPR_KIND_INDEX_PREDICATE, /* index predicate */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
EXPR_KIND_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */
|
2015-07-30 00:37:48 +02:00
|
|
|
EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */
|
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
|
|
|
EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */
|
2019-01-25 11:27:59 +01:00
|
|
|
EXPR_KIND_PARTITION_BOUND, /* partition bound expression */
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */
|
2019-05-22 18:55:34 +02:00
|
|
|
EXPR_KIND_CALL_ARGUMENT, /* procedure argument in CALL */
|
2019-03-30 08:13:09 +01:00
|
|
|
EXPR_KIND_COPY_WHERE, /* WHERE condition in COPY FROM */
|
2019-05-22 18:55:34 +02:00
|
|
|
EXPR_KIND_GENERATED_COLUMN, /* generation expression for a column */
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
} ParseExprKind;
|
|
|
|
|
|
|
|
|
2009-10-31 02:41:31 +01:00
|
|
|
/*
|
|
|
|
* Function signatures for parser hooks
|
|
|
|
*/
|
2010-02-26 03:01:40 +01:00
|
|
|
typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref);
|
|
|
|
typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var);
|
|
|
|
typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref);
|
|
|
|
typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,
|
2017-06-21 20:39:04 +02:00
|
|
|
Oid targetTypeId, int32 targetTypeMod,
|
|
|
|
int location);
|
2009-10-31 02:41:31 +01:00
|
|
|
|
|
|
|
|
2000-09-12 23:07:18 +02:00
|
|
|
/*
|
|
|
|
* State information used during parse analysis
|
2001-02-14 22:35:07 +01:00
|
|
|
*
|
2006-03-14 23:48:25 +01:00
|
|
|
* parentParseState: NULL in a top-level ParseState. When parsing a subquery,
|
|
|
|
* links to current parse state of outer query.
|
|
|
|
*
|
|
|
|
* p_sourcetext: source string that generated the raw parsetree being
|
2014-05-06 18:12:18 +02:00
|
|
|
* analyzed, or NULL if not available. (The string is used only to
|
2006-03-14 23:48:25 +01:00
|
|
|
* generate cursor positions in error messages: we need it to convert
|
|
|
|
* byte-wise locations in parse structures to character-wise cursor
|
|
|
|
* positions.)
|
|
|
|
*
|
2001-02-14 22:35:07 +01:00
|
|
|
* p_rtable: list of RTEs that will become the rangetable of the query.
|
|
|
|
* Note that neither relname nor refname of these entries are necessarily
|
|
|
|
* unique; searching the rtable by name is a bad idea.
|
|
|
|
*
|
2009-01-22 21:16:10 +01:00
|
|
|
* p_joinexprs: list of JoinExpr nodes associated with p_rtable entries.
|
|
|
|
* This is one-for-one with p_rtable, but contains NULLs for non-join
|
|
|
|
* RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins.
|
|
|
|
*
|
2001-02-14 22:35:07 +01:00
|
|
|
* p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that
|
|
|
|
* will become the fromlist of the query's top-level FromExpr node.
|
|
|
|
*
|
2012-08-08 22:41:04 +02:00
|
|
|
* p_namespace: list of ParseNamespaceItems that represents the current
|
|
|
|
* namespace for table and column lookup. (The RTEs listed here may be just
|
|
|
|
* a subset of the whole rtable. See ParseNamespaceItem comments below.)
|
2012-08-08 01:02:54 +02:00
|
|
|
*
|
2017-08-16 06:22:32 +02:00
|
|
|
* p_lateral_active: true if we are currently parsing a LATERAL subexpression
|
2012-08-08 01:02:54 +02:00
|
|
|
* of this parse level. This makes p_lateral_only namespace items visible,
|
|
|
|
* whereas they are not visible when p_lateral_active is FALSE.
|
2003-04-30 00:13:11 +02:00
|
|
|
*
|
2008-10-04 23:56:55 +02:00
|
|
|
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
|
2012-08-08 22:41:04 +02:00
|
|
|
* at the moment. This is entirely different from p_namespace because a CTE
|
|
|
|
* is not an RTE, rather "visibility" means you could make an RTE from it.
|
2008-10-04 23:56:55 +02:00
|
|
|
*
|
2008-10-08 03:14:44 +02:00
|
|
|
* p_future_ctes: list of CommonTableExprs (WITH items) that are not yet
|
2014-05-06 18:12:18 +02:00
|
|
|
* visible due to scope rules. This is used to help improve error messages.
|
2008-10-08 03:14:44 +02:00
|
|
|
*
|
2009-09-09 05:32:52 +02:00
|
|
|
* p_parent_cte: CommonTableExpr that immediately contains the current query,
|
|
|
|
* if any.
|
|
|
|
*
|
2018-04-12 12:22:56 +02:00
|
|
|
* p_target_relation: target relation, if query is INSERT, UPDATE, or DELETE.
|
2017-01-07 21:34:28 +01:00
|
|
|
*
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
* p_target_nsitem: target relation's ParseNamespaceItem.
|
2019-12-26 17:16:42 +01:00
|
|
|
*
|
2017-01-07 21:34:28 +01:00
|
|
|
* p_is_insert: true to process assignment expressions like INSERT, false
|
|
|
|
* to process them like UPDATE. (Note this can change intra-statement, for
|
|
|
|
* cases like INSERT ON CONFLICT UPDATE.)
|
|
|
|
*
|
2008-12-28 19:54:01 +01:00
|
|
|
* p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses.
|
|
|
|
* We collect these while transforming expressions and then transform them
|
|
|
|
* afterwards (so that any resjunk tlist items needed for the sort/group
|
|
|
|
* clauses end up at the end of the query tlist). A WindowDef's location in
|
|
|
|
* this list, counting from 1, is the winref number to use to reference it.
|
2017-01-07 21:34:28 +01:00
|
|
|
*
|
|
|
|
* p_expr_kind: kind of expression we're currently parsing, as per enum above;
|
|
|
|
* EXPR_KIND_NONE when not in an expression.
|
|
|
|
*
|
|
|
|
* p_next_resno: next TargetEntry.resno to assign, starting from 1.
|
|
|
|
*
|
|
|
|
* p_multiassign_exprs: partially-processed MultiAssignRef source expressions.
|
|
|
|
*
|
|
|
|
* p_locking_clause: query's FOR UPDATE/FOR SHARE clause, if any.
|
|
|
|
*
|
|
|
|
* p_locked_from_parent: true if parent query level applies FOR UPDATE/SHARE
|
|
|
|
* to this subquery as a whole.
|
|
|
|
*
|
Change unknown-type literals to type text in SELECT and RETURNING lists.
Previously, we left such literals alone if the query or subquery had
no properties forcing a type decision to be made (such as an ORDER BY or
DISTINCT clause using that output column). This meant that "unknown" could
be an exposed output column type, which has never been a great idea because
it could result in strange failures later on. For example, an outer query
that tried to do any operations on an unknown-type subquery output would
generally fail with some weird error like "failed to find conversion
function from unknown to text" or "could not determine which collation to
use for string comparison". Also, if the case occurred in a CREATE VIEW's
query then the view would have an unknown-type column, causing similar
failures in queries trying to use the view.
To fix, at the tail end of parse analysis of a query, forcibly convert any
remaining "unknown" literals in its SELECT or RETURNING list to type text.
However, provide a switch to suppress that, and use it in the cases of
SELECT inside a set operation or INSERT command. In those cases we already
had type resolution rules that make use of context information from outside
the subquery proper, and we don't want to change that behavior.
Also, change creation of an unknown-type column in a relation from a
warning to a hard error. The error should be unreachable now in CREATE
VIEW or CREATE MATVIEW, but it's still possible to explicitly say "unknown"
in CREATE TABLE or CREATE (composite) TYPE. We want to forbid that because
it's nothing but a foot-gun.
This change creates a pg_upgrade failure case: a matview that contains an
unknown-type column can't be pg_upgraded, because reparsing the matview's
defining query will now decide that the column is of type text, which
doesn't match the cstring-like storage that the old materialized column
would actually have. Add a checking pass to detect that. While at it,
we can detect tables or composite types that would fail, essentially
for free. Those would fail safely anyway later on, but we might as
well fail earlier.
This patch is by me, but it owes something to previous investigations
by Rahila Syed. Also thanks to Ashutosh Bapat and Michael Paquier for
review.
Discussion: https://postgr.es/m/CAH2L28uwwbL9HUM-WR=hromW1Cvamkn7O-g8fPY2m=_7muJ0oA@mail.gmail.com
2017-01-25 15:17:18 +01:00
|
|
|
* p_resolve_unknowns: resolve unknown-type SELECT output columns as type TEXT
|
|
|
|
* (this is true by default).
|
|
|
|
*
|
2017-01-07 21:34:28 +01:00
|
|
|
* p_hasAggs, p_hasWindowFuncs, etc: true if we've found any of the indicated
|
|
|
|
* constructs in the query.
|
|
|
|
*
|
Disallow set-returning functions inside CASE or COALESCE.
When we reimplemented SRFs in commit 69f4b9c85, our initial choice was
to allow the behavior to vary from historical practice in cases where a
SRF call appeared within a conditional-execution construct (currently,
only CASE or COALESCE). But that was controversial to begin with, and
subsequent discussion has resulted in a consensus that it's better to
throw an error instead of executing the query differently from before,
so long as we can provide a reasonably clear error message and a way to
rewrite the query.
Hence, add a parser mechanism to allow detection of such cases during
parse analysis. The mechanism just requires storing, in the ParseState,
a pointer to the set-returning FuncExpr or OpExpr most recently emitted
by parse analysis. Then the parsing functions for CASE and COALESCE can
detect the presence of a SRF in their arguments by noting whether this
pointer changes while analyzing their arguments. Furthermore, if it does,
it provides a suitable error cursor location for the complaint. (This
means that if there's more than one SRF in the arguments, the error will
point at the last one to be analyzed not the first. While connoisseurs of
parsing behavior might find that odd, it's unlikely the average user would
ever notice.)
While at it, we can also provide more specific error messages than before
about some pre-existing restrictions, such as no-SRFs-within-aggregates.
Also, reject at parse time cases where a NULLIF or IS DISTINCT FROM
construct would need to return a set. We've never supported that, but the
restriction is depended on in more subtle ways now, so it seems wise to
detect it at the start.
Also, provide some documentation about how to rewrite a SRF-within-CASE
query using a custom wrapper SRF.
It turns out that the information_schema.user_mapping_options view
contained an instance of exactly the behavior we're now forbidding; but
rewriting it makes it more clear and safer too.
initdb forced because of user_mapping_options change.
Patch by me, with error message suggestions from Alvaro Herrera and
Andres Freund, pursuant to a complaint from Regina Obe.
Discussion: https://postgr.es/m/000001d2d5de$d8d66170$8a832450$@pcorp.us
2017-06-14 05:46:39 +02:00
|
|
|
* p_last_srf: the set-returning FuncExpr or OpExpr most recently found in
|
|
|
|
* the query, or NULL if none.
|
|
|
|
*
|
2017-01-07 21:34:28 +01:00
|
|
|
* p_pre_columnref_hook, etc: optional parser hook functions for modifying the
|
|
|
|
* interpretation of ColumnRefs and ParamRefs.
|
|
|
|
*
|
|
|
|
* p_ref_hook_state: passthrough state for the parser hook functions.
|
2000-02-15 04:38:29 +01:00
|
|
|
*/
|
2009-10-31 02:41:31 +01:00
|
|
|
struct ParseState
|
1997-11-25 23:07:18 +01:00
|
|
|
{
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
ParseState *parentParseState; /* stack link */
|
2006-03-14 23:48:25 +01:00
|
|
|
const char *p_sourcetext; /* source text, or NULL if not available */
|
2000-09-12 23:07:18 +02:00
|
|
|
List *p_rtable; /* range table so far */
|
2009-01-22 21:16:10 +01:00
|
|
|
List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */
|
2001-03-22 05:01:46 +01:00
|
|
|
List *p_joinlist; /* join items so far (will become FromExpr
|
|
|
|
* node's fromlist) */
|
2012-08-08 22:41:04 +02:00
|
|
|
List *p_namespace; /* currently-referenceable RTEs (List of
|
|
|
|
* ParseNamespaceItem) */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
bool p_lateral_active; /* p_lateral_only items visible? */
|
2008-10-04 23:56:55 +02:00
|
|
|
List *p_ctenamespace; /* current namespace for common table exprs */
|
2008-10-08 03:14:44 +02:00
|
|
|
List *p_future_ctes; /* common table exprs not yet in namespace */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
CommonTableExpr *p_parent_cte; /* this query's containing CTE */
|
2018-04-12 12:22:56 +02:00
|
|
|
Relation p_target_relation; /* INSERT/UPDATE/DELETE target rel */
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
ParseNamespaceItem *p_target_nsitem; /* target rel's NSItem, or NULL */
|
2017-01-07 21:34:28 +01:00
|
|
|
bool p_is_insert; /* process assignment like INSERT not UPDATE */
|
2008-12-28 19:54:01 +01:00
|
|
|
List *p_windowdefs; /* raw representations of window clauses */
|
Centralize the logic for detecting misplaced aggregates, window funcs, etc.
Formerly we relied on checking after-the-fact to see if an expression
contained aggregates, window functions, or sub-selects when it shouldn't.
This is grotty, easily forgotten (indeed, we had forgotten to teach
DefineIndex about rejecting window functions), and none too efficient
since it requires extra traversals of the parse tree. To improve matters,
define an enum type that classifies all SQL sub-expressions, store it in
ParseState to show what kind of expression we are currently parsing, and
make transformAggregateCall, transformWindowFuncCall, and transformSubLink
check the expression type and throw error if the type indicates the
construct is disallowed. This allows removal of a large number of ad-hoc
checks scattered around the code base. The enum type is sufficiently
fine-grained that we can still produce error messages of at least the
same specificity as before.
Bringing these error checks together revealed that we'd been none too
consistent about phrasing of the error messages, so standardize the wording
a bit.
Also, rewrite checking of aggregate arguments so that it requires only one
traversal of the arguments, rather than up to three as before.
In passing, clean up some more comments left over from add_missing_from
support, and annotate some tests that I think are dead code now that that's
gone. (I didn't risk actually removing said dead code, though.)
2012-08-10 17:35:33 +02:00
|
|
|
ParseExprKind p_expr_kind; /* what kind of expression we're parsing */
|
2003-04-30 00:13:11 +02:00
|
|
|
int p_next_resno; /* next targetlist resno to assign */
|
Implement UPDATE tab SET (col1,col2,...) = (SELECT ...), ...
This SQL-standard feature allows a sub-SELECT yielding multiple columns
(but only one row) to be used to compute the new values of several columns
to be updated. While the same results can be had with an independent
sub-SELECT per column, such a workaround can require a great deal of
duplicated computation.
The standard actually says that the source for a multi-column assignment
could be any row-valued expression. The implementation used here is
tightly tied to our existing sub-SELECT support and can't handle other
cases; the Bison grammar would have some issues with them too. However,
I don't feel too bad about this since other cases can be converted into
sub-SELECTs. For instance, "SET (a,b,c) = row_valued_function(x)" could
be written "SET (a,b,c) = (SELECT * FROM row_valued_function(x))".
2014-06-18 19:22:25 +02:00
|
|
|
List *p_multiassign_exprs; /* junk tlist entries for multiassign */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */
|
2017-01-07 21:34:28 +01:00
|
|
|
bool p_locked_from_parent; /* parent has marked this subquery
|
|
|
|
* with FOR UPDATE/FOR SHARE */
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
bool p_resolve_unknowns; /* resolve unknown-type SELECT outputs as
|
|
|
|
* type text */
|
2017-01-07 21:34:28 +01:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
QueryEnvironment *p_queryEnv; /* curr env, incl refs to enclosing env */
|
2017-04-01 06:17:18 +02:00
|
|
|
|
2017-01-07 21:34:28 +01:00
|
|
|
/* Flags telling about things found in the query: */
|
1998-01-15 20:00:16 +01:00
|
|
|
bool p_hasAggs;
|
2008-12-28 19:54:01 +01:00
|
|
|
bool p_hasWindowFuncs;
|
2016-09-13 19:54:24 +02:00
|
|
|
bool p_hasTargetSRFs;
|
1998-01-17 05:53:46 +01:00
|
|
|
bool p_hasSubLinks;
|
2011-02-26 00:56:23 +01:00
|
|
|
bool p_hasModifyingCTE;
|
2009-10-31 02:41:31 +01:00
|
|
|
|
Disallow set-returning functions inside CASE or COALESCE.
When we reimplemented SRFs in commit 69f4b9c85, our initial choice was
to allow the behavior to vary from historical practice in cases where a
SRF call appeared within a conditional-execution construct (currently,
only CASE or COALESCE). But that was controversial to begin with, and
subsequent discussion has resulted in a consensus that it's better to
throw an error instead of executing the query differently from before,
so long as we can provide a reasonably clear error message and a way to
rewrite the query.
Hence, add a parser mechanism to allow detection of such cases during
parse analysis. The mechanism just requires storing, in the ParseState,
a pointer to the set-returning FuncExpr or OpExpr most recently emitted
by parse analysis. Then the parsing functions for CASE and COALESCE can
detect the presence of a SRF in their arguments by noting whether this
pointer changes while analyzing their arguments. Furthermore, if it does,
it provides a suitable error cursor location for the complaint. (This
means that if there's more than one SRF in the arguments, the error will
point at the last one to be analyzed not the first. While connoisseurs of
parsing behavior might find that odd, it's unlikely the average user would
ever notice.)
While at it, we can also provide more specific error messages than before
about some pre-existing restrictions, such as no-SRFs-within-aggregates.
Also, reject at parse time cases where a NULLIF or IS DISTINCT FROM
construct would need to return a set. We've never supported that, but the
restriction is depended on in more subtle ways now, so it seems wise to
detect it at the start.
Also, provide some documentation about how to rewrite a SRF-within-CASE
query using a custom wrapper SRF.
It turns out that the information_schema.user_mapping_options view
contained an instance of exactly the behavior we're now forbidding; but
rewriting it makes it more clear and safer too.
initdb forced because of user_mapping_options change.
Patch by me, with error message suggestions from Alvaro Herrera and
Andres Freund, pursuant to a complaint from Regina Obe.
Discussion: https://postgr.es/m/000001d2d5de$d8d66170$8a832450$@pcorp.us
2017-06-14 05:46:39 +02:00
|
|
|
Node *p_last_srf; /* most recent set-returning func/op found */
|
|
|
|
|
2009-10-31 02:41:31 +01:00
|
|
|
/*
|
|
|
|
* Optional hook functions for parser callbacks. These are null unless
|
|
|
|
* set up by the caller of make_parsestate.
|
|
|
|
*/
|
|
|
|
PreParseColumnRefHook p_pre_columnref_hook;
|
|
|
|
PostParseColumnRefHook p_post_columnref_hook;
|
|
|
|
ParseParamRefHook p_paramref_hook;
|
|
|
|
CoerceParamHook p_coerce_param_hook;
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
void *p_ref_hook_state; /* common passthrough link for above */
|
2009-10-31 02:41:31 +01:00
|
|
|
};
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2012-08-08 22:41:04 +02:00
|
|
|
/*
|
|
|
|
* An element of a namespace list.
|
|
|
|
*
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
* The p_nscolumns array contains info showing how to construct Vars
|
|
|
|
* referencing corresponding elements of the RTE's colnames list.
|
|
|
|
*
|
2012-08-08 22:41:04 +02:00
|
|
|
* Namespace items with p_rel_visible set define which RTEs are accessible by
|
|
|
|
* qualified names, while those with p_cols_visible set define which RTEs are
|
|
|
|
* accessible by unqualified names. These sets are different because a JOIN
|
|
|
|
* without an alias does not hide the contained tables (so they must be
|
|
|
|
* visible for qualified references) but it does hide their columns
|
|
|
|
* (unqualified references to the columns refer to the JOIN, not the member
|
|
|
|
* tables, so we must not complain that such a reference is ambiguous).
|
|
|
|
* Various special RTEs such as NEW/OLD for rules may also appear with only
|
|
|
|
* one flag set.
|
|
|
|
*
|
|
|
|
* While processing the FROM clause, namespace items may appear with
|
|
|
|
* p_lateral_only set, meaning they are visible only to LATERAL
|
2014-05-06 18:12:18 +02:00
|
|
|
* subexpressions. (The pstate's p_lateral_active flag tells whether we are
|
2013-05-29 22:58:43 +02:00
|
|
|
* inside such a subexpression at the moment.) If p_lateral_ok is not set,
|
2012-08-08 22:41:04 +02:00
|
|
|
* it's an error to actually use such a namespace item. One might think it
|
|
|
|
* would be better to just exclude such items from visibility, but the wording
|
2014-01-12 01:03:12 +01:00
|
|
|
* of SQL:2008 requires us to do it this way. We also use p_lateral_ok to
|
|
|
|
* forbid LATERAL references to an UPDATE/DELETE target table.
|
2012-08-08 22:41:04 +02:00
|
|
|
*
|
|
|
|
* At no time should a namespace list contain two entries that conflict
|
|
|
|
* according to the rules in checkNameSpaceConflicts; but note that those
|
|
|
|
* are more complicated than "must have different alias names", so in practice
|
|
|
|
* code searching a namespace list has to check for ambiguous references.
|
|
|
|
*/
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
struct ParseNamespaceItem
|
2012-08-08 01:02:54 +02:00
|
|
|
{
|
|
|
|
RangeTblEntry *p_rte; /* The relation's rangetable entry */
|
2019-12-26 17:16:42 +01:00
|
|
|
int p_rtindex; /* The relation's index in the rangetable */
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
/* array of same length as p_rte->eref->colnames: */
|
|
|
|
ParseNamespaceColumn *p_nscolumns; /* per-column data */
|
2012-08-08 22:41:04 +02:00
|
|
|
bool p_rel_visible; /* Relation name is visible? */
|
2013-05-29 22:58:43 +02:00
|
|
|
bool p_cols_visible; /* Column names visible as unqualified refs? */
|
2012-08-08 01:02:54 +02:00
|
|
|
bool p_lateral_only; /* Is only visible to LATERAL expressions? */
|
|
|
|
bool p_lateral_ok; /* If so, does join type allow use? */
|
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.
Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure. Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.
The ParseNamespaceColumn structs also include Var identity information
(varno/varattno). That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.
Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
2020-01-02 17:29:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Data about one column of a ParseNamespaceItem.
|
|
|
|
*
|
|
|
|
* We track the info needed to construct a Var referencing the column
|
|
|
|
* (but only for user-defined columns; system column references and
|
|
|
|
* whole-row references are handled separately).
|
|
|
|
*
|
|
|
|
* p_varno and p_varattno identify the semantic referent, which is a
|
|
|
|
* base-relation column unless the reference is to a join USING column that
|
|
|
|
* isn't semantically equivalent to either join input column (because it is a
|
|
|
|
* FULL join or the input column requires a type coercion). In those cases
|
|
|
|
* p_varno and p_varattno refer to the JOIN RTE.
|
|
|
|
*
|
|
|
|
* p_varnosyn and p_varattnosyn are either identical to p_varno/p_varattno,
|
|
|
|
* or they specify the column's position in an aliased JOIN RTE that hides
|
|
|
|
* the semantic referent RTE's refname. (That could be either the JOIN RTE
|
|
|
|
* in which this ParseNamespaceColumn entry exists, or some lower join level.)
|
|
|
|
*
|
|
|
|
* If an RTE contains a dropped column, its ParseNamespaceColumn struct
|
|
|
|
* is all-zeroes. (Conventionally, test for p_varno == 0 to detect this.)
|
|
|
|
*/
|
|
|
|
struct ParseNamespaceColumn
|
|
|
|
{
|
|
|
|
Index p_varno; /* rangetable index */
|
|
|
|
AttrNumber p_varattno; /* attribute number of the column */
|
|
|
|
Oid p_vartype; /* pg_type OID */
|
|
|
|
int32 p_vartypmod; /* type modifier value */
|
|
|
|
Oid p_varcollid; /* OID of collation, or InvalidOid */
|
|
|
|
Index p_varnosyn; /* rangetable index of syntactic referent */
|
|
|
|
AttrNumber p_varattnosyn; /* attribute number of syntactic referent */
|
|
|
|
};
|
2012-08-08 01:02:54 +02:00
|
|
|
|
2008-09-01 22:42:46 +02:00
|
|
|
/* Support for parser_errposition_callback function */
|
|
|
|
typedef struct ParseCallbackState
|
|
|
|
{
|
|
|
|
ParseState *pstate;
|
|
|
|
int location;
|
2012-11-12 14:10:24 +01:00
|
|
|
ErrorContextCallback errcallback;
|
2008-09-01 22:42:46 +02:00
|
|
|
} ParseCallbackState;
|
|
|
|
|
|
|
|
|
1998-01-19 06:06:41 +01:00
|
|
|
extern ParseState *make_parsestate(ParseState *parentParseState);
|
2007-06-24 00:12:52 +02:00
|
|
|
extern void free_parsestate(ParseState *pstate);
|
2020-03-25 16:57:36 +01:00
|
|
|
extern int parser_errposition(ParseState *pstate, int location);
|
2006-03-14 23:48:25 +01:00
|
|
|
|
2008-09-01 22:42:46 +02:00
|
|
|
extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate,
|
2019-05-22 19:04:48 +02:00
|
|
|
ParseState *pstate, int location);
|
2008-09-01 22:42:46 +02:00
|
|
|
extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate);
|
|
|
|
|
Support subscripting of arbitrary types, not only arrays.
This patch generalizes the subscripting infrastructure so that any
data type can be subscripted, if it provides a handler function to
define what that means. Traditional variable-length (varlena) arrays
all use array_subscript_handler(), while the existing fixed-length
types that support subscripting use raw_array_subscript_handler().
It's expected that other types that want to use subscripting notation
will define their own handlers. (This patch provides no such new
features, though; it only lays the foundation for them.)
To do this, move the parser's semantic processing of subscripts
(including coercion to whatever data type is required) into a
method callback supplied by the handler. On the execution side,
replace the ExecEvalSubscriptingRef* layer of functions with direct
calls to callback-supplied execution routines. (Thus, essentially
no new run-time overhead should be caused by this patch. Indeed,
there is room to remove some overhead by supplying specialized
execution routines. This patch does a little bit in that line,
but more could be done.)
Additional work is required here and there to remove formerly
hard-wired assumptions about the result type, collation, etc
of a SubscriptingRef expression node; and to remove assumptions
that the subscript values must be integers.
One useful side-effect of this is that we now have a less squishy
mechanism for identifying whether a data type is a "true" array:
instead of wiring in weird rules about typlen, we can look to see
if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this
to be bulletproof, we have to forbid user-defined types from using
that handler directly; but there seems no good reason for them to
do so.
This patch also removes assumptions that the number of subscripts
is limited to MAXDIM (6), or indeed has any hard-wired limit.
That limit still applies to types handled by array_subscript_handler
or raw_array_subscript_handler, but to discourage other dependencies
on this constant, I've moved it from c.h to utils/array.h.
Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov,
Peter Eisentraut, Pavel Stehule
Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com
Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
|
|
|
extern void transformContainerType(Oid *containerType, int32 *containerTypmod);
|
2019-02-01 16:50:32 +01:00
|
|
|
|
|
|
|
extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate,
|
2019-05-22 19:04:48 +02:00
|
|
|
Node *containerBase,
|
|
|
|
Oid containerType,
|
|
|
|
int32 containerTypMod,
|
|
|
|
List *indirection,
|
Support subscripting of arbitrary types, not only arrays.
This patch generalizes the subscripting infrastructure so that any
data type can be subscripted, if it provides a handler function to
define what that means. Traditional variable-length (varlena) arrays
all use array_subscript_handler(), while the existing fixed-length
types that support subscripting use raw_array_subscript_handler().
It's expected that other types that want to use subscripting notation
will define their own handlers. (This patch provides no such new
features, though; it only lays the foundation for them.)
To do this, move the parser's semantic processing of subscripts
(including coercion to whatever data type is required) into a
method callback supplied by the handler. On the execution side,
replace the ExecEvalSubscriptingRef* layer of functions with direct
calls to callback-supplied execution routines. (Thus, essentially
no new run-time overhead should be caused by this patch. Indeed,
there is room to remove some overhead by supplying specialized
execution routines. This patch does a little bit in that line,
but more could be done.)
Additional work is required here and there to remove formerly
hard-wired assumptions about the result type, collation, etc
of a SubscriptingRef expression node; and to remove assumptions
that the subscript values must be integers.
One useful side-effect of this is that we now have a less squishy
mechanism for identifying whether a data type is a "true" array:
instead of wiring in weird rules about typlen, we can look to see
if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this
to be bulletproof, we have to forbid user-defined types from using
that handler directly; but there seems no good reason for them to
do so.
This patch also removes assumptions that the number of subscripts
is limited to MAXDIM (6), or indeed has any hard-wired limit.
That limit still applies to types handled by array_subscript_handler
or raw_array_subscript_handler, but to discourage other dependencies
on this constant, I've moved it from c.h to utils/array.h.
Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov,
Peter Eisentraut, Pavel Stehule
Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com
Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
|
|
|
bool isAssignment);
|
|
|
|
|
2008-09-01 22:42:46 +02:00
|
|
|
extern Const *make_const(ParseState *pstate, Value *value, int location);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* PARSE_NODE_H */
|