summaryrefslogtreecommitdiff
path: root/src/include/parser
diff options
context:
space:
mode:
authorTom Lane2021-01-04 16:52:00 +0000
committerTom Lane2021-01-04 16:52:00 +0000
commitc9d5298485b78a37923a23f9af9aa0ade06762db (patch)
tree4e7e39d4035be1dcea11809ab2c43ed69bc4d8c7 /src/include/parser
parent844fe9f159a948377907a63d0ef3fb16dc51ce50 (diff)
Re-implement pl/pgsql's expression and assignment parsing.
Invent new RawParseModes that allow the core grammar to handle pl/pgsql expressions and assignments directly, and thereby get rid of a lot of hackery in pl/pgsql's parser. This moves a good deal of knowledge about pl/pgsql into the core code: notably, we have to invent a CoercionContext that matches pl/pgsql's (rather dubious) historical behavior for assignment coercions. That's getting away from the original idea of pl/pgsql as an arm's-length extension of the core, but really we crossed that bridge a long time ago. The main advantage of doing this is that we can now use the core parser to generate FieldStore and/or SubscriptingRef nodes to handle assignments to pl/pgsql variables that are records or arrays. That fixes a number of cases that had never been implemented in pl/pgsql assignment, such as nested records and array slicing, and it allows pl/pgsql assignment to support the datatype-specific subscripting behaviors introduced in commit c7aba7c14. There are cosmetic benefits too: when a syntax error occurs in a pl/pgsql expression, the error report no longer includes the confusing "SELECT" keyword that used to get prefixed to the expression text. Also, there seem to be some small speed gains. Discussion: https://postgr.es/m/4165684.1607707277@sss.pgh.pa.us
Diffstat (limited to 'src/include/parser')
-rw-r--r--src/include/parser/parse_target.h12
-rw-r--r--src/include/parser/parser.h13
2 files changed, 23 insertions, 2 deletions
diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h
index 9d3637747d..1a7b1a9277 100644
--- a/src/include/parser/parse_target.h
+++ b/src/include/parser/parse_target.h
@@ -36,6 +36,18 @@ extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
char *colname, int attrno,
List *indirection,
int location);
+extern Node *transformAssignmentIndirection(ParseState *pstate,
+ Node *basenode,
+ const char *targetName,
+ bool targetIsSubscripting,
+ Oid targetTypeId,
+ int32 targetTypMod,
+ Oid targetCollation,
+ List *indirection,
+ ListCell *indirection_cell,
+ Node *rhs,
+ CoercionContext ccontext,
+ int location);
extern List *checkInsertTargets(ParseState *pstate, List *cols,
List **attrnos);
extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 80d90027cc..853b0f1606 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -27,12 +27,21 @@
* RAW_PARSE_TYPE_NAME: parse a type name, and return a one-element List
* containing a TypeName node.
*
- * ... more to come ...
+ * RAW_PARSE_PLPGSQL_EXPR: parse a PL/pgSQL expression, and return
+ * a one-element List containing a RawStmt node.
+ *
+ * RAW_PARSE_PLPGSQL_ASSIGNn: parse a PL/pgSQL assignment statement,
+ * and return a one-element List containing a RawStmt node. "n"
+ * gives the number of dotted names comprising the target ColumnRef.
*/
typedef enum
{
RAW_PARSE_DEFAULT = 0,
- RAW_PARSE_TYPE_NAME
+ RAW_PARSE_TYPE_NAME,
+ RAW_PARSE_PLPGSQL_EXPR,
+ RAW_PARSE_PLPGSQL_ASSIGN1,
+ RAW_PARSE_PLPGSQL_ASSIGN2,
+ RAW_PARSE_PLPGSQL_ASSIGN3
} RawParseMode;
/* Values for the backslash_quote GUC */