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
|
|
|
*
|
|
|
|
*
|
2024-01-04 02:49:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2024, 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
|
|
|
|
{
|
|
|
|
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 */
|
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_PARTITION, /* window definition PARTITION BY */
|
|
|
|
EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */
|
|
|
|
EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */
|
|
|
|
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 */
|
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_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 */
|
2022-03-28 16:45:58 +02:00
|
|
|
EXPR_KIND_MERGE_WHEN, /* MERGE WHEN [NOT] MATCHED condition */
|
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_GROUP_BY, /* GROUP BY */
|
|
|
|
EXPR_KIND_ORDER_BY, /* ORDER BY */
|
|
|
|
EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */
|
|
|
|
EXPR_KIND_LIMIT, /* LIMIT */
|
|
|
|
EXPR_KIND_OFFSET, /* OFFSET */
|
Add RETURNING support to MERGE.
This allows a RETURNING clause to be appended to a MERGE query, to
return values based on each row inserted, updated, or deleted. As with
plain INSERT, UPDATE, and DELETE commands, the returned values are
based on the new contents of the target table for INSERT and UPDATE
actions, and on its old contents for DELETE actions. Values from the
source relation may also be returned.
As with INSERT/UPDATE/DELETE, the output of MERGE ... RETURNING may be
used as the source relation for other operations such as WITH queries
and COPY commands.
Additionally, a special function merge_action() is provided, which
returns 'INSERT', 'UPDATE', or 'DELETE', depending on the action
executed for each row. The merge_action() function can be used
anywhere in the RETURNING list, including in arbitrary expressions and
subqueries, but it is an error to use it anywhere outside of a MERGE
query's RETURNING list.
Dean Rasheed, reviewed by Isaac Morland, Vik Fearing, Alvaro Herrera,
Gurjeet Singh, Jian He, Jeff Davis, Merlin Moncure, Peter Eisentraut,
and Wolfgang Walther.
Discussion: http://postgr.es/m/CAEZATCWePEGQR5LBn-vD6SfeLZafzEm2Qy_L_Oky2=qw2w3Pzg@mail.gmail.com
2024-03-17 14:58:59 +01:00
|
|
|
EXPR_KIND_RETURNING, /* RETURNING in INSERT/UPDATE/DELETE */
|
|
|
|
EXPR_KIND_MERGE_RETURNING, /* RETURNING in MERGE */
|
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_VALUES, /* VALUES */
|
2017-01-16 21:23:11 +01:00
|
|
|
EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */
|
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_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 */
|
Extended statistics on expressions
Allow defining extended statistics on expressions, not just just on
simple column references. With this commit, expressions are supported
by all existing extended statistics kinds, improving the same types of
estimates. A simple example may look like this:
CREATE TABLE t (a int);
CREATE STATISTICS s ON mod(a,10), mod(a,20) FROM t;
ANALYZE t;
The collected statistics are useful e.g. to estimate queries with those
expressions in WHERE or GROUP BY clauses:
SELECT * FROM t WHERE mod(a,10) = 0 AND mod(a,20) = 0;
SELECT 1 FROM t GROUP BY mod(a,10), mod(a,20);
This introduces new internal statistics kind 'e' (expressions) which is
built automatically when the statistics object definition includes any
expressions. This represents single-expression statistics, as if there
was an expression index (but without the index maintenance overhead).
The statistics is stored in pg_statistics_ext_data as an array of
composite types, which is possible thanks to 79f6a942bd.
CREATE STATISTICS allows building statistics on a single expression, in
which case in which case it's not possible to specify statistics kinds.
A new system view pg_stats_ext_exprs can be used to display expression
statistics, similarly to pg_stats and pg_stats_ext views.
ALTER TABLE ... ALTER COLUMN ... TYPE now treats indexes the same way it
treats indexes, i.e. it drops and recreates the statistics. This means
all statistics are reset, and we no longer try to preserve at least the
functional dependencies. This should not be a major issue in practice,
as the functional dependencies actually rely on per-column statistics,
which were always reset anyway.
Author: Tomas Vondra
Reviewed-by: Justin Pryzby, Dean Rasheed, Zhihong Yu
Discussion: https://postgr.es/m/ad7891d2-e90c-b446-9fe2-7419143847d7%40enterprisedb.com
2021-03-26 23:22:01 +01:00
|
|
|
EXPR_KIND_STATS_EXPRESSION, /* extended statistics expression */
|
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_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */
|
|
|
|
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-01-19 23:48:16 +01: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 */
|
|
|
|
EXPR_KIND_GENERATED_COLUMN, /* generation expression for a column */
|
2021-02-01 13:54:59 +01:00
|
|
|
EXPR_KIND_CYCLE_MARK, /* cycle mark value */
|
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
|
|
|
|
*/
|
|
|
|
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,
|
|
|
|
Oid targetTypeId, int32 targetTypeMod,
|
|
|
|
int location);
|
|
|
|
|
|
|
|
|
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
|
|
|
|
* analyzed, or NULL if not available. (The string is used only to
|
|
|
|
* 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.
|
|
|
|
*
|
2022-12-06 16:09:24 +01:00
|
|
|
* p_rteperminfos: list of RTEPermissionInfo containing an entry corresponding
|
|
|
|
* to each RTE_RELATION entry in p_rtable.
|
|
|
|
*
|
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.
|
|
|
|
*
|
Make Vars be outer-join-aware.
Traditionally we used the same Var struct to represent the value
of a table column everywhere in parse and plan trees. This choice
predates our support for SQL outer joins, and it's really a pretty
bad idea with outer joins, because the Var's value can depend on
where it is in the tree: it might go to NULL above an outer join.
So expression nodes that are equal() per equalfuncs.c might not
represent the same value, which is a huge correctness hazard for
the planner.
To improve this, decorate Var nodes with a bitmapset showing
which outer joins (identified by RTE indexes) may have nulled
them at the point in the parse tree where the Var appears.
This allows us to trust that equal() Vars represent the same value.
A certain amount of klugery is still needed to cope with cases
where we re-order two outer joins, but it's possible to make it
work without sacrificing that core principle. PlaceHolderVars
receive similar decoration for the same reason.
In the planner, we include these outer join bitmapsets into the relids
that an expression is considered to depend on, and in consequence also
add outer-join relids to the relids of join RelOptInfos. This allows
us to correctly perceive whether an expression can be calculated above
or below a particular outer join.
This change affects FDWs that want to plan foreign joins. They *must*
follow suit when labeling foreign joins in order to match with the
core planner, but for many purposes (if postgres_fdw is any guide)
they'd prefer to consider only base relations within the join.
To support both requirements, redefine ForeignScan.fs_relids as
base+OJ relids, and add a new field fs_base_relids that's set up by
the core planner.
Large though it is, this commit just does the minimum necessary to
install the new mechanisms and get check-world passing again.
Follow-up patches will perform some cleanup. (The README additions
and comments mention some stuff that will appear in the follow-up.)
Patch by me; thanks to Richard Guo for review.
Discussion: https://postgr.es/m/830269.1656693747@sss.pgh.pa.us
2023-01-30 19:16:20 +01:00
|
|
|
* p_nullingrels: list of Bitmapsets associated with p_rtable entries, each
|
|
|
|
* containing the set of outer-join RTE indexes that can null that relation
|
|
|
|
* at the current point in the parse tree. This is one-for-one with p_rtable,
|
|
|
|
* but may be shorter than p_rtable, in which case the missing entries are
|
|
|
|
* implicitly empty (NULL). That rule allows us to save work when the query
|
|
|
|
* contains no outer 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
|
|
|
|
* visible due to scope rules. This is used to help improve error messages.
|
|
|
|
*
|
2009-09-09 05:32:52 +02:00
|
|
|
* p_parent_cte: CommonTableExpr that immediately contains the current query,
|
|
|
|
* if any.
|
|
|
|
*
|
2022-03-28 16:45:58 +02:00
|
|
|
* p_target_relation: target relation, if query is INSERT/UPDATE/DELETE/MERGE
|
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 */
|
2022-12-06 16:09:24 +01:00
|
|
|
List *p_rteperminfos; /* list of RTEPermissionInfo nodes for each
|
|
|
|
* RTE_RELATION entry in rtable */
|
2009-01-22 21:16:10 +01:00
|
|
|
List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */
|
Make Vars be outer-join-aware.
Traditionally we used the same Var struct to represent the value
of a table column everywhere in parse and plan trees. This choice
predates our support for SQL outer joins, and it's really a pretty
bad idea with outer joins, because the Var's value can depend on
where it is in the tree: it might go to NULL above an outer join.
So expression nodes that are equal() per equalfuncs.c might not
represent the same value, which is a huge correctness hazard for
the planner.
To improve this, decorate Var nodes with a bitmapset showing
which outer joins (identified by RTE indexes) may have nulled
them at the point in the parse tree where the Var appears.
This allows us to trust that equal() Vars represent the same value.
A certain amount of klugery is still needed to cope with cases
where we re-order two outer joins, but it's possible to make it
work without sacrificing that core principle. PlaceHolderVars
receive similar decoration for the same reason.
In the planner, we include these outer join bitmapsets into the relids
that an expression is considered to depend on, and in consequence also
add outer-join relids to the relids of join RelOptInfos. This allows
us to correctly perceive whether an expression can be calculated above
or below a particular outer join.
This change affects FDWs that want to plan foreign joins. They *must*
follow suit when labeling foreign joins in order to match with the
core planner, but for many purposes (if postgres_fdw is any guide)
they'd prefer to consider only base relations within the join.
To support both requirements, redefine ForeignScan.fs_relids as
base+OJ relids, and add a new field fs_base_relids that's set up by
the core planner.
Large though it is, this commit just does the minimum necessary to
install the new mechanisms and get check-world passing again.
Follow-up patches will perform some cleanup. (The README additions
and comments mention some stuff that will appear in the follow-up.)
Patch by me; thanks to Richard Guo for review.
Discussion: https://postgr.es/m/830269.1656693747@sss.pgh.pa.us
2023-01-30 19:16:20 +01:00
|
|
|
List *p_nullingrels; /* Bitmapsets showing nulling outer joins */
|
2000-09-29 20:21:41 +02: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) */
|
2012-08-08 01:02: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 */
|
2009-09-09 05:32:52 +02:00
|
|
|
CommonTableExpr *p_parent_cte; /* this query's containing CTE */
|
2022-03-28 16:45:58 +02:00
|
|
|
Relation p_target_relation; /* INSERT/UPDATE/DELETE/MERGE 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 */
|
2006-04-30 20:30:40 +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 */
|
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
|
|
|
bool p_resolve_unknowns; /* resolve unknown-type SELECT outputs as
|
|
|
|
* type text */
|
2017-01-07 21:34:28 +01:00
|
|
|
|
2017-04-01 06:17:18 +02:00
|
|
|
QueryEnvironment *p_queryEnv; /* curr env, incl refs to enclosing env */
|
|
|
|
|
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;
|
|
|
|
void *p_ref_hook_state; /* common passthrough link for above */
|
|
|
|
};
|
1997-11-25 23:07:18 +01:00
|
|
|
|
2012-08-08 22:41:04 +02:00
|
|
|
/*
|
|
|
|
* An element of a namespace list.
|
|
|
|
*
|
2021-03-31 10:52:37 +02:00
|
|
|
* p_names contains the table name and column names exposed by this nsitem.
|
2021-03-31 17:09:24 +02:00
|
|
|
* (Typically it's equal to p_rte->eref, but for a JOIN USING alias it's
|
|
|
|
* equal to p_rte->join_using_alias. Since the USING columns will be the
|
|
|
|
* join's first N columns, the net effect is just that we expose only those
|
|
|
|
* join columns via this nsitem.)
|
2021-03-31 10:52:37 +02:00
|
|
|
*
|
2022-12-06 16:09:24 +01:00
|
|
|
* p_rte and p_rtindex link to the underlying rangetable entry, and
|
|
|
|
* p_perminfo to the entry in rteperminfos.
|
2021-03-31 10:52:37 +02: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
|
|
|
* The p_nscolumns array contains info showing how to construct Vars
|
2021-03-31 10:52:37 +02:00
|
|
|
* referencing the names appearing in the p_names->colnames 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
|
|
|
*
|
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).
|
2022-07-20 10:29:42 +02:00
|
|
|
* Conversely, a subquery without an alias does not hide the columns selected
|
|
|
|
* by the subquery, but it does hide the auto-generated relation name (so the
|
|
|
|
* subquery columns are visible for unqualified references only). Various
|
|
|
|
* special RTEs such as NEW/OLD for rules may also appear with only one flag
|
|
|
|
* set.
|
2012-08-08 22:41:04 +02:00
|
|
|
*
|
|
|
|
* While processing the FROM clause, namespace items may appear with
|
|
|
|
* p_lateral_only set, meaning they are visible only to LATERAL
|
|
|
|
* subexpressions. (The pstate's p_lateral_active flag tells whether we are
|
|
|
|
* inside such a subexpression at the moment.) If p_lateral_ok is not set,
|
|
|
|
* 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
|
|
|
{
|
2021-03-31 10:52:37 +02:00
|
|
|
Alias *p_names; /* Table and column names */
|
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 */
|
2022-12-06 16:09:24 +01:00
|
|
|
RTEPermissionInfo *p_perminfo; /* The relation's rteperminfos entry */
|
2021-03-31 10:52:37 +02:00
|
|
|
/* array of same length as p_names->colnames: */
|
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
|
|
|
ParseNamespaceColumn *p_nscolumns; /* per-column data */
|
2012-08-08 22:41:04 +02:00
|
|
|
bool p_rel_visible; /* Relation name is visible? */
|
|
|
|
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 */
|
2021-02-01 13:54:59 +01:00
|
|
|
bool p_dontexpand; /* not included in star expansion */
|
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
|
|
|
};
|
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,
|
|
|
|
ParseState *pstate, int location);
|
|
|
|
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,
|
|
|
|
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);
|
Remove Value node struct
The Value node struct is a weird construct. It is its own node type,
but most of the time, it actually has a node type of Integer, Float,
String, or BitString. As a consequence, the struct name and the node
type don't match most of the time, and so it has to be treated
specially a lot. There doesn't seem to be any value in the special
construct. There is very little code that wants to accept all Value
variants but nothing else (and even if it did, this doesn't provide
any convenient way to check it), and most code wants either just one
particular node type (usually String), or it accepts a broader set of
node types besides just Value.
This change removes the Value struct and node type and replaces them
by separate Integer, Float, String, and BitString node types that are
proper node types and structs of their own and behave mostly like
normal node types.
Also, this removes the T_Null node tag, which was previously also a
possible variant of Value but wasn't actually used outside of the
Value contained in A_Const. Replace that by an isnull field in
A_Const.
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/5ba6bc5b-3f95-04f2-2419-f8ddb4c046fb@enterprisedb.com
2021-09-09 07:58:12 +02:00
|
|
|
extern Const *make_const(ParseState *pstate, A_Const *aconst);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
1997-11-25 23:07:18 +01:00
|
|
|
#endif /* PARSE_NODE_H */
|