YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/postgres/src/backend/parser/analyze.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * analyze.c
4
 *    transform the raw parse tree into a query tree
5
 *
6
 * For optimizable statements, we are careful to obtain a suitable lock on
7
 * each referenced table, and other modules of the backend preserve or
8
 * re-obtain these locks before depending on the results.  It is therefore
9
 * okay to do significant semantic analysis of these statements.  For
10
 * utility commands, no locks are obtained here (and if they were, we could
11
 * not be sure we'd still have them at execution).  Hence the general rule
12
 * for utility commands is to just dump them into a Query node untransformed.
13
 * DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are exceptions because they
14
 * contain optimizable statements, which we should transform.
15
 *
16
 *
17
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
18
 * Portions Copyright (c) 1994, Regents of the University of California
19
 *
20
 *  src/backend/parser/analyze.c
21
 *
22
 *-------------------------------------------------------------------------
23
 */
24
25
#include "postgres.h"
26
27
#include "access/sysattr.h"
28
#include "access/xact.h"
29
#include "catalog/catalog.h"
30
#include "catalog/pg_type.h"
31
#include "commands/dbcommands.h"
32
#include "miscadmin.h"
33
#include "nodes/makefuncs.h"
34
#include "nodes/nodeFuncs.h"
35
#include "optimizer/var.h"
36
#include "parser/analyze.h"
37
#include "parser/parse_agg.h"
38
#include "parser/parse_clause.h"
39
#include "parser/parse_coerce.h"
40
#include "parser/parse_collate.h"
41
#include "parser/parse_cte.h"
42
#include "parser/parse_expr.h"
43
#include "parser/parse_func.h"
44
#include "parser/parse_oper.h"
45
#include "parser/parse_param.h"
46
#include "parser/parse_relation.h"
47
#include "parser/parse_target.h"
48
#include "parser/parsetree.h"
49
#include "rewrite/rewriteManip.h"
50
#include "utils/rel.h"
51
52
#include "pg_yb_utils.h"
53
54
/* Hook for plugins to get control at end of parse analysis */
55
post_parse_analyze_hook_type post_parse_analyze_hook = NULL;
56
57
static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree);
58
static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
59
static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
60
static List *transformInsertRow(ParseState *pstate, List *exprlist,
61
           List *stmtcols, List *icolumns, List *attrnos,
62
           bool strip_indirection);
63
static OnConflictExpr *transformOnConflictClause(ParseState *pstate,
64
              OnConflictClause *onConflictClause);
65
static int  count_rowexpr_columns(ParseState *pstate, Node *expr);
66
static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
67
static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt);
68
static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
69
static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
70
              bool isTopLevel, List **targetlist);
71
static void determineRecursiveColTypes(ParseState *pstate,
72
               Node *larg, List *nrtargetlist);
73
static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
74
static List *transformReturningList(ParseState *pstate, List *returningList);
75
static List *transformUpdateTargetList(ParseState *pstate,
76
              List *targetList);
77
static Query *transformDeclareCursorStmt(ParseState *pstate,
78
               DeclareCursorStmt *stmt);
79
static Query *transformExplainStmt(ParseState *pstate,
80
           ExplainStmt *stmt);
81
static Query *transformCreateTableAsStmt(ParseState *pstate,
82
               CreateTableAsStmt *stmt);
83
static Query *transformCallStmt(ParseState *pstate,
84
          CallStmt *stmt);
85
static void transformLockingClause(ParseState *pstate, Query *qry,
86
             LockingClause *lc, bool pushedDown);
87
#ifdef RAW_EXPRESSION_COVERAGE_TEST
88
static bool test_raw_expression_coverage(Node *node, void *context);
89
#endif
90
91
92
/*
93
 * parse_analyze
94
 *    Analyze a raw parse tree and transform it to Query form.
95
 *
96
 * Optionally, information about $n parameter types can be supplied.
97
 * References to $n indexes not defined by paramTypes[] are disallowed.
98
 *
99
 * The result is a Query node.  Optimizable statements require considerable
100
 * transformation, while utility-type statements are simply hung off
101
 * a dummy CMD_UTILITY Query node.
102
 */
103
Query *
104
parse_analyze(RawStmt *parseTree, const char *sourceText,
105
        Oid *paramTypes, int numParams,
106
        QueryEnvironment *queryEnv)
107
151k
{
108
151k
  ParseState *pstate = make_parsestate(NULL);
109
151k
  Query    *query;
110
111
151k
  Assert(sourceText != NULL); /* required as of 8.4 */
112
113
151k
  pstate->p_sourcetext = sourceText;
114
115
151k
  if (numParams > 0)
116
229
    parse_fixed_parameters(pstate, paramTypes, numParams);
117
118
151k
  pstate->p_queryEnv = queryEnv;
119
120
151k
  query = transformTopLevelStmt(pstate, parseTree);
121
122
151k
  if (pstate->p_target_relation &&
123
151k
    
pstate->p_target_relation->rd_rel->relpersistence == 52.9k
RELPERSISTENCE_TEMP52.9k
124
151k
    && 
IsYugaByteEnabled()326
)
125
326
  {
126
326
    SetTxnWithPGRel();
127
326
  }
128
129
151k
  if (post_parse_analyze_hook)
130
148k
    (*post_parse_analyze_hook) (pstate, query);
131
132
151k
  free_parsestate(pstate);
133
134
151k
  return query;
135
151k
}
136
137
/*
138
 * parse_analyze_varparams
139
 *
140
 * This variant is used when it's okay to deduce information about $n
141
 * symbol datatypes from context.  The passed-in paramTypes[] array can
142
 * be modified or enlarged (via repalloc).
143
 */
144
Query *
145
parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
146
            Oid **paramTypes, int *numParams)
147
408k
{
148
408k
  ParseState *pstate = make_parsestate(NULL);
149
408k
  Query    *query;
150
151
408k
  Assert(sourceText != NULL); /* required as of 8.4 */
152
153
408k
  pstate->p_sourcetext = sourceText;
154
155
408k
  parse_variable_parameters(pstate, paramTypes, numParams);
156
157
408k
  query = transformTopLevelStmt(pstate, parseTree);
158
159
408k
  if (pstate->p_target_relation &&
160
408k
    
pstate->p_target_relation->rd_rel->relpersistence == 245k
RELPERSISTENCE_TEMP245k
161
408k
    && 
IsYugaByteEnabled()66
)
162
66
  {
163
66
    SetTxnWithPGRel();
164
66
  }
165
166
  /* make sure all is well with parameter types */
167
408k
  check_variable_parameters(pstate, query);
168
169
408k
  if (post_parse_analyze_hook)
170
407k
    (*post_parse_analyze_hook) (pstate, query);
171
172
408k
  free_parsestate(pstate);
173
174
408k
  return query;
175
408k
}
176
177
/*
178
 * parse_sub_analyze
179
 *    Entry point for recursively analyzing a sub-statement.
180
 */
181
Query *
182
parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
183
          CommonTableExpr *parentCTE,
184
          bool locked_from_parent,
185
          bool resolve_unknowns)
186
16.2k
{
187
16.2k
  ParseState *pstate = make_parsestate(parentParseState);
188
16.2k
  Query    *query;
189
190
16.2k
  pstate->p_parent_cte = parentCTE;
191
16.2k
  pstate->p_locked_from_parent = locked_from_parent;
192
16.2k
  pstate->p_resolve_unknowns = resolve_unknowns;
193
194
16.2k
  query = transformStmt(pstate, parseTree);
195
196
16.2k
  free_parsestate(pstate);
197
198
16.2k
  return query;
199
16.2k
}
200
201
/*
202
 * transformTopLevelStmt -
203
 *    transform a Parse tree into a Query tree.
204
 *
205
 * This function is just responsible for transferring statement location data
206
 * from the RawStmt into the finished Query.
207
 */
208
Query *
209
transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
210
572k
{
211
572k
  Query    *result;
212
213
  /* We're at top level, so allow SELECT INTO */
214
572k
  result = transformOptionalSelectInto(pstate, parseTree->stmt);
215
216
572k
  result->stmt_location = parseTree->stmt_location;
217
572k
  result->stmt_len = parseTree->stmt_len;
218
219
572k
  return result;
220
572k
}
221
222
/*
223
 * transformOptionalSelectInto -
224
 *    If SELECT has INTO, convert it to CREATE TABLE AS.
225
 *
226
 * The only thing we do here that we don't do in transformStmt() is to
227
 * convert SELECT ... INTO into CREATE TABLE AS.  Since utility statements
228
 * aren't allowed within larger statements, this is only allowed at the top
229
 * of the parse tree, and so we only try it before entering the recursive
230
 * transformStmt() processing.
231
 */
232
static Query *
233
transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
234
575k
{
235
575k
  if (IsA(parseTree, SelectStmt))
236
124k
  {
237
124k
    SelectStmt *stmt = (SelectStmt *) parseTree;
238
239
    /* If it's a set-operation tree, drill down to leftmost SelectStmt */
240
126k
    while (
stmt126k
&& stmt->op != SETOP_NONE)
241
1.87k
      stmt = stmt->larg;
242
124k
    Assert(stmt && IsA(stmt, SelectStmt) &&stmt->larg == NULL);
243
244
124k
    if (stmt->intoClause)
245
3
    {
246
3
      CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
247
248
0
      ctas->query = parseTree;
249
3
      ctas->into = stmt->intoClause;
250
3
      ctas->relkind = OBJECT_TABLE;
251
3
      ctas->is_select_into = true;
252
253
      /*
254
       * Remove the intoClause from the SelectStmt.  This makes it safe
255
       * for transformSelectStmt to complain if it finds intoClause set
256
       * (implying that the INTO appeared in a disallowed place).
257
       */
258
3
      stmt->intoClause = NULL;
259
260
3
      parseTree = (Node *) ctas;
261
3
    }
262
124k
  }
263
264
575k
  return transformStmt(pstate, parseTree);
265
575k
}
266
267
/*
268
 * transformStmt -
269
 *    recursively transform a Parse tree into a Query tree.
270
 */
271
Query *
272
transformStmt(ParseState *pstate, Node *parseTree)
273
594k
{
274
594k
  Query    *result;
275
276
  /*
277
   * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements;
278
   * we can't just run it on everything because raw_expression_tree_walker()
279
   * doesn't claim to handle utility statements.
280
   */
281
#ifdef RAW_EXPRESSION_COVERAGE_TEST
282
  switch (nodeTag(parseTree))
283
  {
284
    case T_SelectStmt:
285
    case T_InsertStmt:
286
    case T_UpdateStmt:
287
    case T_DeleteStmt:
288
      (void) test_raw_expression_coverage(parseTree, NULL);
289
      break;
290
    default:
291
      break;
292
  }
293
#endif              /* RAW_EXPRESSION_COVERAGE_TEST */
294
295
594k
  switch (nodeTag(parseTree))
296
594k
  {
297
      /*
298
       * Optimizable statements
299
       */
300
271k
    case T_InsertStmt:
301
271k
      result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
302
271k
      break;
303
304
4.41k
    case T_DeleteStmt:
305
4.41k
      result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
306
4.41k
      break;
307
308
29.3k
    case T_UpdateStmt:
309
29.3k
      result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
310
29.3k
      break;
311
312
141k
    case T_SelectStmt:
313
141k
      {
314
141k
        SelectStmt *n = (SelectStmt *) parseTree;
315
316
141k
        if (n->valuesLists)
317
1.23k
          result = transformValuesClause(pstate, n);
318
140k
        else if (n->op == SETOP_NONE)
319
139k
          result = transformSelectStmt(pstate, n);
320
470
        else
321
470
          result = transformSetOperationStmt(pstate, n);
322
141k
      }
323
141k
      break;
324
325
      /*
326
       * Special cases
327
       */
328
1.55k
    case T_DeclareCursorStmt:
329
1.55k
      result = transformDeclareCursorStmt(pstate,
330
1.55k
                        (DeclareCursorStmt *) parseTree);
331
1.55k
      break;
332
333
2.73k
    case T_ExplainStmt:
334
2.73k
      result = transformExplainStmt(pstate,
335
2.73k
                      (ExplainStmt *) parseTree);
336
2.73k
      break;
337
338
110
    case T_CreateTableAsStmt:
339
110
      result = transformCreateTableAsStmt(pstate,
340
110
                        (CreateTableAsStmt *) parseTree);
341
110
      break;
342
343
426
    case T_CallStmt:
344
426
      result = transformCallStmt(pstate,
345
426
                     (CallStmt *) parseTree);
346
426
      break;
347
348
143k
    default:
349
350
      /*
351
       * other statements don't require any transformation; just return
352
       * the original parsetree with a Query node plastered on top.
353
       */
354
143k
      result = makeNode(Query);
355
0
      result->commandType = CMD_UTILITY;
356
143k
      result->utilityStmt = (Node *) parseTree;
357
143k
      break;
358
594k
  }
359
360
  /* Mark as original query until we learn differently */
361
593k
  result->querySource = QSRC_ORIGINAL;
362
593k
  result->canSetTag = true;
363
364
593k
  return result;
365
594k
}
366
367
/*
368
 * analyze_requires_snapshot
369
 *    Returns true if a snapshot must be set before doing parse analysis
370
 *    on the given raw parse tree.
371
 *
372
 * Classification here should match transformStmt().
373
 */
374
bool
375
analyze_requires_snapshot(RawStmt *parseTree)
376
1.05M
{
377
1.05M
  bool    result;
378
379
1.05M
  switch (nodeTag(parseTree->stmt))
380
1.05M
  {
381
      /*
382
       * Optimizable statements
383
       */
384
512k
    case T_InsertStmt:
385
517k
    case T_DeleteStmt:
386
543k
    case T_UpdateStmt:
387
742k
    case T_SelectStmt:
388
742k
      result = true;
389
742k
      break;
390
391
      /*
392
       * Special cases
393
       */
394
1.75k
    case T_DeclareCursorStmt:
395
5.15k
    case T_ExplainStmt:
396
5.24k
    case T_CreateTableAsStmt:
397
      /* yes, because we must analyze the contained statement */
398
5.24k
      result = true;
399
5.24k
      break;
400
401
2.27k
    case T_BackfillIndexStmt:
402
2.27k
      result = false;
403
2.27k
      break;
404
405
304k
    default:
406
      /* other utility statements don't have any real parse analysis */
407
304k
      result = false;
408
304k
      break;
409
1.05M
  }
410
411
1.05M
  return result;
412
1.05M
}
413
414
/*
415
 * transformDeleteStmt -
416
 *    transforms a Delete Statement
417
 */
418
static Query *
419
transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
420
4.41k
{
421
4.41k
  Query    *qry = makeNode(Query);
422
0
  ParseNamespaceItem *nsitem;
423
4.41k
  Node     *qual;
424
425
4.41k
  qry->commandType = CMD_DELETE;
426
427
  /* process the WITH clause independently of all else */
428
4.41k
  if (stmt->withClause)
429
1
  {
430
1
    qry->hasRecursive = stmt->withClause->recursive;
431
1
    qry->cteList = transformWithClause(pstate, stmt->withClause);
432
1
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
433
1
  }
434
435
  /* set up range table with just the result rel */
436
4.41k
  qry->resultRelation = setTargetTable(pstate, stmt->relation,
437
4.41k
                     stmt->relation->inh,
438
4.41k
                     true,
439
4.41k
                     ACL_DELETE);
440
441
  /* grab the namespace item made by setTargetTable */
442
4.41k
  nsitem = (ParseNamespaceItem *) llast(pstate->p_namespace);
443
444
  /* there's no DISTINCT in DELETE */
445
4.41k
  qry->distinctClause = NIL;
446
447
  /* subqueries in USING cannot access the result relation */
448
4.41k
  nsitem->p_lateral_only = true;
449
4.41k
  nsitem->p_lateral_ok = false;
450
451
  /*
452
   * The USING clause is non-standard SQL syntax, and is equivalent in
453
   * functionality to the FROM list that can be specified for UPDATE. The
454
   * USING keyword is used rather than FROM because FROM is already a
455
   * keyword in the DELETE syntax.
456
   */
457
4.41k
  transformFromClause(pstate, stmt->usingClause);
458
459
  /* remaining clauses can reference the result relation normally */
460
4.41k
  nsitem->p_lateral_only = false;
461
4.41k
  nsitem->p_lateral_ok = true;
462
463
4.41k
  qual = transformWhereClause(pstate, stmt->whereClause,
464
4.41k
                EXPR_KIND_WHERE, "WHERE");
465
466
4.41k
  qry->returningList = transformReturningList(pstate, stmt->returningList);
467
468
  /* done building the range table and jointree */
469
4.41k
  qry->rtable = pstate->p_rtable;
470
4.41k
  qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
471
472
4.41k
  qry->hasSubLinks = pstate->p_hasSubLinks;
473
4.41k
  qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
474
4.41k
  qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
475
4.41k
  qry->hasAggs = pstate->p_hasAggs;
476
477
4.41k
  assign_query_collations(pstate, qry);
478
479
  /* this must be done after collations, for reliable comparison of exprs */
480
4.41k
  if (pstate->p_hasAggs)
481
0
    parseCheckAggregates(pstate, qry);
482
483
4.41k
  return qry;
484
4.41k
}
485
486
/*
487
 * transformInsertStmt -
488
 *    transform an Insert Statement
489
 */
490
static Query *
491
transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
492
271k
{
493
271k
  Query    *qry = makeNode(Query);
494
0
  SelectStmt *selectStmt = (SelectStmt *) stmt->selectStmt;
495
271k
  List     *exprList = NIL;
496
271k
  bool    isGeneralSelect;
497
271k
  List     *sub_rtable;
498
271k
  List     *sub_namespace;
499
271k
  List     *icolumns;
500
271k
  List     *attrnos;
501
271k
  RangeTblEntry *rte;
502
271k
  RangeTblRef *rtr;
503
271k
  ListCell   *icols;
504
271k
  ListCell   *attnos;
505
271k
  ListCell   *lc;
506
271k
  bool    isOnConflictUpdate;
507
271k
  AclMode   targetPerms;
508
509
  /* There can't be any outer WITH to worry about */
510
271k
  Assert(pstate->p_ctenamespace == NIL);
511
512
271k
  qry->commandType = CMD_INSERT;
513
271k
  pstate->p_is_insert = true;
514
515
  /* process the WITH clause independently of all else */
516
271k
  if (stmt->withClause)
517
656
  {
518
656
    qry->hasRecursive = stmt->withClause->recursive;
519
656
    qry->cteList = transformWithClause(pstate, stmt->withClause);
520
656
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
521
656
  }
522
523
271k
  qry->override = stmt->override;
524
525
271k
  isOnConflictUpdate = (stmt->onConflictClause &&
526
271k
              
stmt->onConflictClause->action == ONCONFLICT_UPDATE7.62k
);
527
528
  /*
529
   * We have three cases to deal with: DEFAULT VALUES (selectStmt == NULL),
530
   * VALUES list, or general SELECT input.  We special-case VALUES, both for
531
   * efficiency and so we can handle DEFAULT specifications.
532
   *
533
   * The grammar allows attaching ORDER BY, LIMIT, FOR UPDATE, or WITH to a
534
   * VALUES clause.  If we have any of those, treat it as a general SELECT;
535
   * so it will work, but you can't use DEFAULT items together with those.
536
   */
537
271k
  isGeneralSelect = (selectStmt && 
(271k
selectStmt->valuesLists == 271k
NIL271k
||
538
271k
                    
selectStmt->sortClause != 269k
NIL269k
||
539
271k
                    
selectStmt->limitOffset != NULL269k
||
540
271k
                    
selectStmt->limitCount != NULL269k
||
541
271k
                    
selectStmt->lockingClause != 269k
NIL269k
||
542
271k
                    
selectStmt->withClause != NULL269k
));
543
544
  /*
545
   * If a non-nil rangetable/namespace was passed in, and we are doing
546
   * INSERT/SELECT, arrange to pass the rangetable/namespace down to the
547
   * SELECT.  This can only happen if we are inside a CREATE RULE, and in
548
   * that case we want the rule's OLD and NEW rtable entries to appear as
549
   * part of the SELECT's rtable, not as outer references for it.  (Kluge!)
550
   * The SELECT's joinlist is not affected however.  We must do this before
551
   * adding the target table to the INSERT's rtable.
552
   */
553
271k
  if (isGeneralSelect)
554
1.16k
  {
555
1.16k
    sub_rtable = pstate->p_rtable;
556
1.16k
    pstate->p_rtable = NIL;
557
1.16k
    sub_namespace = pstate->p_namespace;
558
1.16k
    pstate->p_namespace = NIL;
559
1.16k
  }
560
269k
  else
561
269k
  {
562
269k
    sub_rtable = NIL;   /* not used, but keep compiler quiet */
563
269k
    sub_namespace = NIL;
564
269k
  }
565
566
  /*
567
   * Must get write lock on INSERT target table before scanning SELECT, else
568
   * we will grab the wrong kind of initial lock if the target table is also
569
   * mentioned in the SELECT part.  Note that the target table is not added
570
   * to the joinlist or namespace.
571
   */
572
271k
  targetPerms = ACL_INSERT;
573
271k
  if (isOnConflictUpdate)
574
7.35k
    targetPerms |= ACL_UPDATE;
575
271k
  qry->resultRelation = setTargetTable(pstate, stmt->relation,
576
271k
                     false, false, targetPerms);
577
578
  /* Validate stmt->cols list, or build default list if no list given */
579
271k
  icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
580
271k
  Assert(list_length(icolumns) == list_length(attrnos));
581
582
  /*
583
   * Determine which variant of INSERT we have.
584
   */
585
271k
  if (selectStmt == NULL)
586
66
  {
587
    /*
588
     * We have INSERT ... DEFAULT VALUES.  We can handle this case by
589
     * emitting an empty targetlist --- all columns will be defaulted when
590
     * the planner expands the targetlist.
591
     */
592
66
    exprList = NIL;
593
66
  }
594
271k
  else if (isGeneralSelect)
595
1.16k
  {
596
    /*
597
     * We make the sub-pstate a child of the outer pstate so that it can
598
     * see any Param definitions supplied from above.  Since the outer
599
     * pstate's rtable and namespace are presently empty, there are no
600
     * side-effects of exposing names the sub-SELECT shouldn't be able to
601
     * see.
602
     */
603
1.16k
    ParseState *sub_pstate = make_parsestate(pstate);
604
1.16k
    Query    *selectQuery;
605
606
    /*
607
     * Process the source SELECT.
608
     *
609
     * It is important that this be handled just like a standalone SELECT;
610
     * otherwise the behavior of SELECT within INSERT might be different
611
     * from a stand-alone SELECT. (Indeed, Postgres up through 6.5 had
612
     * bugs of just that nature...)
613
     *
614
     * The sole exception is that we prevent resolving unknown-type
615
     * outputs as TEXT.  This does not change the semantics since if the
616
     * column type matters semantically, it would have been resolved to
617
     * something else anyway.  Doing this lets us resolve such outputs as
618
     * the target column's type, which we handle below.
619
     */
620
1.16k
    sub_pstate->p_rtable = sub_rtable;
621
1.16k
    sub_pstate->p_joinexprs = NIL; /* sub_rtable has no joins */
622
1.16k
    sub_pstate->p_namespace = sub_namespace;
623
1.16k
    sub_pstate->p_resolve_unknowns = false;
624
625
1.16k
    selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
626
627
1.16k
    free_parsestate(sub_pstate);
628
629
    /* The grammar should have produced a SELECT */
630
1.16k
    if (!IsA(selectQuery, Query) ||
631
1.16k
      selectQuery->commandType != CMD_SELECT)
632
0
      elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
633
634
    /*
635
     * Make the source be a subquery in the INSERT's rangetable, and add
636
     * it to the INSERT's joinlist.
637
     */
638
1.16k
    rte = addRangeTableEntryForSubquery(pstate,
639
1.16k
                      selectQuery,
640
1.16k
                      makeAlias("*SELECT*", NIL),
641
1.16k
                      false,
642
1.16k
                      false);
643
1.16k
    rtr = makeNode(RangeTblRef);
644
    /* assume new rte is at end */
645
0
    rtr->rtindex = list_length(pstate->p_rtable);
646
1.16k
    Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
647
1.16k
    pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
648
649
    /*----------
650
     * Generate an expression list for the INSERT that selects all the
651
     * non-resjunk columns from the subquery.  (INSERT's tlist must be
652
     * separate from the subquery's tlist because we may add columns,
653
     * insert datatype coercions, etc.)
654
     *
655
     * HACK: unknown-type constants and params in the SELECT's targetlist
656
     * are copied up as-is rather than being referenced as subquery
657
     * outputs.  This is to ensure that when we try to coerce them to
658
     * the target column's datatype, the right things happen (see
659
     * special cases in coerce_type).  Otherwise, this fails:
660
     *    INSERT INTO foo SELECT 'bar', ... FROM baz
661
     *----------
662
     */
663
1.16k
    exprList = NIL;
664
1.16k
    foreach(lc, selectQuery->targetList)
665
3.10k
    {
666
3.10k
      TargetEntry *tle = (TargetEntry *) lfirst(lc);
667
3.10k
      Expr     *expr;
668
669
3.10k
      if (tle->resjunk)
670
0
        continue;
671
3.10k
      if (tle->expr &&
672
3.10k
        (IsA(tle->expr, Const) ||
IsA1.25k
(tle->expr, Param)) &&
673
3.10k
        
exprType((Node *) tle->expr) == 1.85k
UNKNOWNOID1.85k
)
674
735
        expr = tle->expr;
675
2.36k
      else
676
2.36k
      {
677
2.36k
        Var      *var = makeVarFromTargetEntry(rtr->rtindex, tle);
678
679
2.36k
        var->location = exprLocation((Node *) tle->expr);
680
2.36k
        expr = (Expr *) var;
681
2.36k
      }
682
3.10k
      exprList = lappend(exprList, expr);
683
3.10k
    }
684
685
    /* Prepare row for assignment to target table */
686
1.16k
    exprList = transformInsertRow(pstate, exprList,
687
1.16k
                    stmt->cols,
688
1.16k
                    icolumns, attrnos,
689
1.16k
                    false);
690
1.16k
  }
691
269k
  else if (list_length(selectStmt->valuesLists) > 1)
692
1.13k
  {
693
    /*
694
     * Process INSERT ... VALUES with multiple VALUES sublists. We
695
     * generate a VALUES RTE holding the transformed expression lists, and
696
     * build up a targetlist containing Vars that reference the VALUES
697
     * RTE.
698
     */
699
1.13k
    List     *exprsLists = NIL;
700
1.13k
    List     *coltypes = NIL;
701
1.13k
    List     *coltypmods = NIL;
702
1.13k
    List     *colcollations = NIL;
703
1.13k
    int     sublist_length = -1;
704
1.13k
    bool    lateral = false;
705
706
1.13k
    Assert(selectStmt->intoClause == NULL);
707
708
1.13k
    foreach(lc, selectStmt->valuesLists)
709
110k
    {
710
110k
      List     *sublist = (List *) lfirst(lc);
711
712
      /*
713
       * Do basic expression transformation (same as a ROW() expr, but
714
       * allow SetToDefault at top level)
715
       */
716
110k
      sublist = transformExpressionList(pstate, sublist,
717
110k
                        EXPR_KIND_VALUES, true);
718
719
      /*
720
       * All the sublists must be the same length, *after*
721
       * transformation (which might expand '*' into multiple items).
722
       * The VALUES RTE can't handle anything different.
723
       */
724
110k
      if (sublist_length < 0)
725
1.13k
      {
726
        /* Remember post-transformation length of first sublist */
727
1.13k
        sublist_length = list_length(sublist);
728
1.13k
      }
729
109k
      else if (sublist_length != list_length(sublist))
730
0
      {
731
0
        ereport(ERROR,
732
0
            (errcode(ERRCODE_SYNTAX_ERROR),
733
0
             errmsg("VALUES lists must all be the same length"),
734
0
             parser_errposition(pstate,
735
0
                      exprLocation((Node *) sublist))));
736
0
      }
737
738
      /*
739
       * Prepare row for assignment to target table.  We process any
740
       * indirection on the target column specs normally but then strip
741
       * off the resulting field/array assignment nodes, since we don't
742
       * want the parsed statement to contain copies of those in each
743
       * VALUES row.  (It's annoying to have to transform the
744
       * indirection specs over and over like this, but avoiding it
745
       * would take some really messy refactoring of
746
       * transformAssignmentIndirection.)
747
       */
748
110k
      sublist = transformInsertRow(pstate, sublist,
749
110k
                     stmt->cols,
750
110k
                     icolumns, attrnos,
751
110k
                     true);
752
753
      /*
754
       * We must assign collations now because assign_query_collations
755
       * doesn't process rangetable entries.  We just assign all the
756
       * collations independently in each row, and don't worry about
757
       * whether they are consistent vertically.  The outer INSERT query
758
       * isn't going to care about the collations of the VALUES columns,
759
       * so it's not worth the effort to identify a common collation for
760
       * each one here.  (But note this does have one user-visible
761
       * consequence: INSERT ... VALUES won't complain about conflicting
762
       * explicit COLLATEs in a column, whereas the same VALUES
763
       * construct in another context would complain.)
764
       */
765
110k
      assign_list_collations(pstate, sublist);
766
767
110k
      exprsLists = lappend(exprsLists, sublist);
768
110k
    }
769
770
    /*
771
     * Construct column type/typmod/collation lists for the VALUES RTE.
772
     * Every expression in each column has been coerced to the type/typmod
773
     * of the corresponding target column or subfield, so it's sufficient
774
     * to look at the exprType/exprTypmod of the first row.  We don't care
775
     * about the collation labeling, so just fill in InvalidOid for that.
776
     */
777
1.13k
    foreach(lc, (List *) linitial(exprsLists))
778
4.64k
    {
779
4.64k
      Node     *val = (Node *) lfirst(lc);
780
781
4.64k
      coltypes = lappend_oid(coltypes, exprType(val));
782
4.64k
      coltypmods = lappend_int(coltypmods, exprTypmod(val));
783
4.64k
      colcollations = lappend_oid(colcollations, InvalidOid);
784
4.64k
    }
785
786
    /*
787
     * Ordinarily there can't be any current-level Vars in the expression
788
     * lists, because the namespace was empty ... but if we're inside
789
     * CREATE RULE, then NEW/OLD references might appear.  In that case we
790
     * have to mark the VALUES RTE as LATERAL.
791
     */
792
1.13k
    if (list_length(pstate->p_rtable) != 1 &&
793
1.13k
      
contain_vars_of_level((Node *) exprsLists, 0)1
)
794
1
      lateral = true;
795
796
    /*
797
     * Generate the VALUES RTE
798
     */
799
1.13k
    rte = addRangeTableEntryForValues(pstate, exprsLists,
800
1.13k
                      coltypes, coltypmods, colcollations,
801
1.13k
                      NULL, lateral, true);
802
1.13k
    rtr = makeNode(RangeTblRef);
803
    /* assume new rte is at end */
804
0
    rtr->rtindex = list_length(pstate->p_rtable);
805
1.13k
    Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
806
1.13k
    pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
807
808
    /*
809
     * Generate list of Vars referencing the RTE
810
     */
811
1.13k
    expandRTE(rte, rtr->rtindex, 0, -1, false, NULL, &exprList);
812
813
    /*
814
     * Re-apply any indirection on the target column specs to the Vars
815
     */
816
1.13k
    exprList = transformInsertRow(pstate, exprList,
817
1.13k
                    stmt->cols,
818
1.13k
                    icolumns, attrnos,
819
1.13k
                    false);
820
1.13k
  }
821
268k
  else
822
268k
  {
823
    /*
824
     * Process INSERT ... VALUES with a single VALUES sublist.  We treat
825
     * this case separately for efficiency.  The sublist is just computed
826
     * directly as the Query's targetlist, with no VALUES RTE.  So it
827
     * works just like a SELECT without any FROM.
828
     */
829
268k
    List     *valuesLists = selectStmt->valuesLists;
830
831
268k
    Assert(list_length(valuesLists) == 1);
832
268k
    Assert(selectStmt->intoClause == NULL);
833
834
    /*
835
     * Do basic expression transformation (same as a ROW() expr, but allow
836
     * SetToDefault at top level)
837
     */
838
268k
    exprList = transformExpressionList(pstate,
839
268k
                       (List *) linitial(valuesLists),
840
268k
                       EXPR_KIND_VALUES_SINGLE,
841
268k
                       true);
842
843
    /* Prepare row for assignment to target table */
844
268k
    exprList = transformInsertRow(pstate, exprList,
845
268k
                    stmt->cols,
846
268k
                    icolumns, attrnos,
847
268k
                    false);
848
268k
  }
849
850
  /*
851
   * Generate query's target list using the computed list of expressions.
852
   * Also, mark all the target columns as needing insert permissions.
853
   */
854
271k
  rte = pstate->p_target_rangetblentry;
855
271k
  qry->targetList = NIL;
856
271k
  icols = list_head(icolumns);
857
271k
  attnos = list_head(attrnos);
858
271k
  foreach(lc, exprList)
859
693k
  {
860
693k
    Expr     *expr = (Expr *) lfirst(lc);
861
693k
    ResTarget  *col;
862
693k
    AttrNumber  attr_num;
863
693k
    TargetEntry *tle;
864
865
693k
    col = lfirst_node(ResTarget, icols);
866
693k
    attr_num = (AttrNumber) lfirst_int(attnos);
867
868
693k
    tle = makeTargetEntry(expr,
869
693k
                attr_num,
870
693k
                col->name,
871
693k
                false);
872
693k
    qry->targetList = lappend(qry->targetList, tle);
873
874
693k
    rte->insertedCols = bms_add_member(rte->insertedCols,
875
693k
                       attr_num - YBGetFirstLowInvalidAttributeNumber(pstate->p_target_relation));
876
877
693k
    icols = lnext(icols);
878
693k
    attnos = lnext(attnos);
879
693k
  }
880
881
  /* Process ON CONFLICT, if any. */
882
271k
  if (stmt->onConflictClause)
883
7.63k
    qry->onConflict = transformOnConflictClause(pstate,
884
7.63k
                          stmt->onConflictClause);
885
886
  /*
887
   * If we have a RETURNING clause, we need to add the target relation to
888
   * the query namespace before processing it, so that Var references in
889
   * RETURNING will work.  Also, remove any namespace entries added in a
890
   * sub-SELECT or VALUES list.
891
   */
892
271k
  if (stmt->returningList)
893
205
  {
894
205
    pstate->p_namespace = NIL;
895
205
    addRTEtoQuery(pstate, pstate->p_target_rangetblentry,
896
205
            false, true, true);
897
205
    qry->returningList = transformReturningList(pstate,
898
205
                          stmt->returningList);
899
205
  }
900
901
  /* done building the range table and jointree */
902
271k
  qry->rtable = pstate->p_rtable;
903
271k
  qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
904
905
271k
  qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
906
271k
  qry->hasSubLinks = pstate->p_hasSubLinks;
907
908
271k
  assign_query_collations(pstate, qry);
909
910
271k
  return qry;
911
271k
}
912
913
/*
914
 * Prepare an INSERT row for assignment to the target table.
915
 *
916
 * exprlist: transformed expressions for source values; these might come from
917
 * a VALUES row, or be Vars referencing a sub-SELECT or VALUES RTE output.
918
 * stmtcols: original target-columns spec for INSERT (we just test for NIL)
919
 * icolumns: effective target-columns spec (list of ResTarget)
920
 * attrnos: integer column numbers (must be same length as icolumns)
921
 * strip_indirection: if true, remove any field/array assignment nodes
922
 */
923
static List *
924
transformInsertRow(ParseState *pstate, List *exprlist,
925
           List *stmtcols, List *icolumns, List *attrnos,
926
           bool strip_indirection)
927
381k
{
928
381k
  List     *result;
929
381k
  ListCell   *lc;
930
381k
  ListCell   *icols;
931
381k
  ListCell   *attnos;
932
933
  /*
934
   * Check length of expr list.  It must not have more expressions than
935
   * there are target columns.  We allow fewer, but only if no explicit
936
   * columns list was given (the remaining columns are implicitly
937
   * defaulted).  Note we must check this *after* transformation because
938
   * that could expand '*' into multiple items.
939
   */
940
381k
  if (list_length(exprlist) > list_length(icolumns))
941
381k
    ereport(ERROR,
942
381k
        (errcode(ERRCODE_SYNTAX_ERROR),
943
381k
         errmsg("INSERT has more expressions than target columns"),
944
381k
         parser_errposition(pstate,
945
381k
                  exprLocation(list_nth(exprlist,
946
381k
                              list_length(icolumns))))));
947
381k
  if (stmtcols != NIL &&
948
381k
    
list_length(exprlist) < list_length(icolumns)196k
)
949
2
  {
950
    /*
951
     * We can get here for cases like INSERT ... SELECT (a,b,c) FROM ...
952
     * where the user accidentally created a RowExpr instead of separate
953
     * columns.  Add a suitable hint if that seems to be the problem,
954
     * because the main error message is quite misleading for this case.
955
     * (If there's no stmtcols, you'll get something about data type
956
     * mismatch, which is less misleading so we don't worry about giving a
957
     * hint in that case.)
958
     */
959
2
    ereport(ERROR,
960
2
        (errcode(ERRCODE_SYNTAX_ERROR),
961
2
         errmsg("INSERT has more target columns than expressions"),
962
2
         ((list_length(exprlist) == 1 &&
963
2
           count_rowexpr_columns(pstate, linitial(exprlist)) ==
964
2
           list_length(icolumns)) ?
965
2
          errhint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?") : 0),
966
2
         parser_errposition(pstate,
967
2
                  exprLocation(list_nth(icolumns,
968
2
                              list_length(exprlist))))));
969
2
  }
970
971
  /*
972
   * Prepare columns for assignment to target table.
973
   */
974
381k
  result = NIL;
975
381k
  icols = list_head(icolumns);
976
381k
  attnos = list_head(attrnos);
977
381k
  foreach(lc, exprlist)
978
1.11M
  {
979
1.11M
    Expr     *expr = (Expr *) lfirst(lc);
980
1.11M
    ResTarget  *col;
981
982
1.11M
    col = lfirst_node(ResTarget, icols);
983
984
1.11M
    expr = transformAssignedExpr(pstate, expr,
985
1.11M
                   EXPR_KIND_INSERT_TARGET,
986
1.11M
                   col->name,
987
1.11M
                   lfirst_int(attnos),
988
1.11M
                   col->indirection,
989
1.11M
                   col->location);
990
991
1.11M
    if (strip_indirection)
992
420k
    {
993
420k
      while (expr)
994
420k
      {
995
420k
        if (IsA(expr, FieldStore))
996
16
        {
997
16
          FieldStore *fstore = (FieldStore *) expr;
998
999
16
          expr = (Expr *) linitial(fstore->newvals);
1000
16
        }
1001
420k
        else if (IsA(expr, ArrayRef))
1002
22
        {
1003
22
          ArrayRef   *aref = (ArrayRef *) expr;
1004
1005
22
          if (aref->refassgnexpr == NULL)
1006
0
            break;
1007
22
          expr = aref->refassgnexpr;
1008
22
        }
1009
420k
        else
1010
420k
          break;
1011
420k
      }
1012
420k
    }
1013
1014
1.11M
    result = lappend(result, expr);
1015
1016
1.11M
    icols = lnext(icols);
1017
1.11M
    attnos = lnext(attnos);
1018
1.11M
  }
1019
1020
381k
  return result;
1021
381k
}
1022
1023
/*
1024
 * transformOnConflictClause -
1025
 *    transforms an OnConflictClause in an INSERT
1026
 */
1027
static OnConflictExpr *
1028
transformOnConflictClause(ParseState *pstate,
1029
              OnConflictClause *onConflictClause)
1030
7.62k
{
1031
7.62k
  List     *arbiterElems;
1032
7.62k
  Node     *arbiterWhere;
1033
7.62k
  Oid     arbiterConstraint;
1034
7.62k
  List     *onConflictSet = NIL;
1035
7.62k
  Node     *onConflictWhere = NULL;
1036
7.62k
  RangeTblEntry *exclRte = NULL;
1037
7.62k
  int     exclRelIndex = 0;
1038
7.62k
  List     *exclRelTlist = NIL;
1039
7.62k
  OnConflictExpr *result;
1040
1041
  /* Process the arbiter clause, ON CONFLICT ON (...) */
1042
7.62k
  transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems,
1043
7.62k
                 &arbiterWhere, &arbiterConstraint);
1044
1045
  /* Process DO UPDATE */
1046
7.62k
  if (onConflictClause->action == ONCONFLICT_UPDATE)
1047
7.36k
  {
1048
7.36k
    Relation  targetrel = pstate->p_target_relation;
1049
1050
    /*
1051
     * All INSERT expressions have been parsed, get ready for potentially
1052
     * existing SET statements that need to be processed like an UPDATE.
1053
     */
1054
7.36k
    pstate->p_is_insert = false;
1055
1056
    /*
1057
     * Add range table entry for the EXCLUDED pseudo relation.  relkind is
1058
     * set to composite to signal that we're not dealing with an actual
1059
     * relation, and no permission checks are required on it.  (We'll
1060
     * check the actual target relation, instead.)
1061
     */
1062
7.36k
    exclRte = addRangeTableEntryForRelation(pstate,
1063
7.36k
                        targetrel,
1064
7.36k
                        makeAlias("excluded", NIL),
1065
7.36k
                        false, false);
1066
7.36k
    exclRte->relkind = RELKIND_COMPOSITE_TYPE;
1067
7.36k
    exclRte->requiredPerms = 0;
1068
    /* other permissions fields in exclRte are already empty */
1069
1070
7.36k
    exclRelIndex = list_length(pstate->p_rtable);
1071
1072
    /* Create EXCLUDED rel's targetlist for use by EXPLAIN */
1073
7.36k
    exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel,
1074
7.36k
                             exclRelIndex);
1075
1076
    /*
1077
     * Add EXCLUDED and the target RTE to the namespace, so that they can
1078
     * be used in the UPDATE subexpressions.
1079
     */
1080
7.36k
    addRTEtoQuery(pstate, exclRte, false, true, true);
1081
7.36k
    addRTEtoQuery(pstate, pstate->p_target_rangetblentry,
1082
7.36k
            false, true, true);
1083
1084
    /*
1085
     * Now transform the UPDATE subexpressions.
1086
     */
1087
7.36k
    onConflictSet =
1088
7.36k
      transformUpdateTargetList(pstate, onConflictClause->targetList);
1089
1090
7.36k
    onConflictWhere = transformWhereClause(pstate,
1091
7.36k
                         onConflictClause->whereClause,
1092
7.36k
                         EXPR_KIND_WHERE, "WHERE");
1093
7.36k
  }
1094
1095
  /* Finally, build ON CONFLICT DO [NOTHING | UPDATE] expression */
1096
7.62k
  result = makeNode(OnConflictExpr);
1097
1098
0
  result->action = onConflictClause->action;
1099
7.62k
  result->arbiterElems = arbiterElems;
1100
7.62k
  result->arbiterWhere = arbiterWhere;
1101
7.62k
  result->constraint = arbiterConstraint;
1102
7.62k
  result->onConflictSet = onConflictSet;
1103
7.62k
  result->onConflictWhere = onConflictWhere;
1104
7.62k
  result->exclRelIndex = exclRelIndex;
1105
7.62k
  result->exclRelTlist = exclRelTlist;
1106
1107
7.62k
  return result;
1108
7.62k
}
1109
1110
1111
/*
1112
 * BuildOnConflictExcludedTargetlist
1113
 *    Create target list for the EXCLUDED pseudo-relation of ON CONFLICT,
1114
 *    representing the columns of targetrel with varno exclRelIndex.
1115
 *
1116
 * Note: Exported for use in the rewriter.
1117
 */
1118
List *
1119
BuildOnConflictExcludedTargetlist(Relation targetrel,
1120
                  Index exclRelIndex)
1121
7.36k
{
1122
7.36k
  List     *result = NIL;
1123
7.36k
  int     attno;
1124
7.36k
  Var      *var;
1125
7.36k
  TargetEntry *te;
1126
1127
  /*
1128
   * Note that resnos of the tlist must correspond to attnos of the
1129
   * underlying relation, hence we need entries for dropped columns too.
1130
   */
1131
22.2k
  for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); 
attno++14.8k
)
1132
14.8k
  {
1133
14.8k
    Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno);
1134
14.8k
    char     *name;
1135
1136
14.8k
    if (attr->attisdropped)
1137
5
    {
1138
      /*
1139
       * can't use atttypid here, but it doesn't really matter what type
1140
       * the Const claims to be.
1141
       */
1142
5
      var = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
1143
5
      name = "";
1144
5
    }
1145
14.8k
    else
1146
14.8k
    {
1147
14.8k
      var = makeVar(exclRelIndex, attno + 1,
1148
14.8k
              attr->atttypid, attr->atttypmod,
1149
14.8k
              attr->attcollation,
1150
14.8k
              0);
1151
14.8k
      name = pstrdup(NameStr(attr->attname));
1152
14.8k
    }
1153
1154
14.8k
    te = makeTargetEntry((Expr *) var,
1155
14.8k
               attno + 1,
1156
14.8k
               name,
1157
14.8k
               false);
1158
1159
14.8k
    result = lappend(result, te);
1160
14.8k
  }
1161
1162
  /*
1163
   * Add a whole-row-Var entry to support references to "EXCLUDED.*".  Like
1164
   * the other entries in the EXCLUDED tlist, its resno must match the Var's
1165
   * varattno, else the wrong things happen while resolving references in
1166
   * setrefs.c.  This is against normal conventions for targetlists, but
1167
   * it's okay since we don't use this as a real tlist.
1168
   */
1169
7.36k
  var = makeVar(exclRelIndex, InvalidAttrNumber,
1170
7.36k
          targetrel->rd_rel->reltype,
1171
7.36k
          -1, InvalidOid, 0);
1172
7.36k
  te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true);
1173
7.36k
  result = lappend(result, te);
1174
1175
7.36k
  return result;
1176
7.36k
}
1177
1178
1179
/*
1180
 * count_rowexpr_columns -
1181
 *    get number of columns contained in a ROW() expression;
1182
 *    return -1 if expression isn't a RowExpr or a Var referencing one.
1183
 *
1184
 * This is currently used only for hint purposes, so we aren't terribly
1185
 * tense about recognizing all possible cases.  The Var case is interesting
1186
 * because that's what we'll get in the INSERT ... SELECT (...) case.
1187
 */
1188
static int
1189
count_rowexpr_columns(ParseState *pstate, Node *expr)
1190
0
{
1191
0
  if (expr == NULL)
1192
0
    return -1;
1193
0
  if (IsA(expr, RowExpr))
1194
0
    return list_length(((RowExpr *) expr)->args);
1195
0
  if (IsA(expr, Var))
1196
0
  {
1197
0
    Var      *var = (Var *) expr;
1198
0
    AttrNumber  attnum = var->varattno;
1199
1200
0
    if (attnum > 0 && var->vartype == RECORDOID)
1201
0
    {
1202
0
      RangeTblEntry *rte;
1203
1204
0
      rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
1205
0
      if (rte->rtekind == RTE_SUBQUERY)
1206
0
      {
1207
        /* Subselect-in-FROM: examine sub-select's output expr */
1208
0
        TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
1209
0
                          attnum);
1210
1211
0
        if (ste == NULL || ste->resjunk)
1212
0
          return -1;
1213
0
        expr = (Node *) ste->expr;
1214
0
        if (IsA(expr, RowExpr))
1215
0
          return list_length(((RowExpr *) expr)->args);
1216
0
      }
1217
0
    }
1218
0
  }
1219
0
  return -1;
1220
0
}
1221
1222
1223
/*
1224
 * transformSelectStmt -
1225
 *    transforms a Select Statement
1226
 *
1227
 * Note: this covers only cases with no set operations and no VALUES lists;
1228
 * see below for the other cases.
1229
 */
1230
static Query *
1231
transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1232
139k
{
1233
139k
  Query    *qry = makeNode(Query);
1234
0
  Node     *qual;
1235
139k
  ListCell   *l;
1236
1237
139k
  qry->commandType = CMD_SELECT;
1238
1239
  /* process the WITH clause independently of all else */
1240
139k
  if (stmt->withClause)
1241
2.20k
  {
1242
2.20k
    qry->hasRecursive = stmt->withClause->recursive;
1243
2.20k
    qry->cteList = transformWithClause(pstate, stmt->withClause);
1244
2.20k
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1245
2.20k
  }
1246
1247
  /* Complain if we get called from someplace where INTO is not allowed */
1248
139k
  if (stmt->intoClause)
1249
139k
    ereport(ERROR,
1250
139k
        (errcode(ERRCODE_SYNTAX_ERROR),
1251
139k
         errmsg("SELECT ... INTO is not allowed here"),
1252
139k
         parser_errposition(pstate,
1253
139k
                  exprLocation((Node *) stmt->intoClause))));
1254
1255
  /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */
1256
139k
  pstate->p_locking_clause = stmt->lockingClause;
1257
1258
  /* make WINDOW info available for window functions, too */
1259
139k
  pstate->p_windowdefs = stmt->windowClause;
1260
1261
  /* process the FROM clause */
1262
139k
  transformFromClause(pstate, stmt->fromClause);
1263
1264
  /* transform targetlist */
1265
139k
  qry->targetList = transformTargetList(pstate, stmt->targetList,
1266
139k
                      EXPR_KIND_SELECT_TARGET);
1267
1268
  /* mark column origins */
1269
139k
  markTargetListOrigins(pstate, qry->targetList);
1270
1271
  /* transform WHERE */
1272
139k
  qual = transformWhereClause(pstate, stmt->whereClause,
1273
139k
                EXPR_KIND_WHERE, "WHERE");
1274
1275
  /* initial processing of HAVING clause is much like WHERE clause */
1276
139k
  qry->havingQual = transformWhereClause(pstate, stmt->havingClause,
1277
139k
                       EXPR_KIND_HAVING, "HAVING");
1278
1279
  /*
1280
   * Transform sorting/grouping stuff.  Do ORDER BY first because both
1281
   * transformGroupClause and transformDistinctClause need the results. Note
1282
   * that these functions can also change the targetList, so it's passed to
1283
   * them by reference.
1284
   */
1285
139k
  qry->sortClause = transformSortClause(pstate,
1286
139k
                      stmt->sortClause,
1287
139k
                      &qry->targetList,
1288
139k
                      EXPR_KIND_ORDER_BY,
1289
139k
                      false /* allow SQL92 rules */ );
1290
1291
139k
  qry->groupClause = transformGroupClause(pstate,
1292
139k
                      stmt->groupClause,
1293
139k
                      &qry->groupingSets,
1294
139k
                      &qry->targetList,
1295
139k
                      qry->sortClause,
1296
139k
                      EXPR_KIND_GROUP_BY,
1297
139k
                      false /* allow SQL92 rules */ );
1298
1299
139k
  if (stmt->distinctClause == NIL)
1300
139k
  {
1301
139k
    qry->distinctClause = NIL;
1302
139k
    qry->hasDistinctOn = false;
1303
139k
  }
1304
715
  else if (linitial(stmt->distinctClause) == NULL)
1305
42
  {
1306
    /* We had SELECT DISTINCT */
1307
42
    qry->distinctClause = transformDistinctClause(pstate,
1308
42
                            &qry->targetList,
1309
42
                            qry->sortClause,
1310
42
                            false);
1311
42
    qry->hasDistinctOn = false;
1312
42
  }
1313
673
  else
1314
673
  {
1315
    /* We had SELECT DISTINCT ON */
1316
673
    qry->distinctClause = transformDistinctOnClause(pstate,
1317
673
                            stmt->distinctClause,
1318
673
                            &qry->targetList,
1319
673
                            qry->sortClause);
1320
673
    qry->hasDistinctOn = true;
1321
673
  }
1322
1323
  /* transform LIMIT */
1324
139k
  qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
1325
139k
                      EXPR_KIND_OFFSET, "OFFSET");
1326
139k
  qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
1327
139k
                       EXPR_KIND_LIMIT, "LIMIT");
1328
1329
  /* transform window clauses after we have seen all window functions */
1330
139k
  qry->windowClause = transformWindowDefinitions(pstate,
1331
139k
                           pstate->p_windowdefs,
1332
139k
                           &qry->targetList);
1333
1334
  /* resolve any still-unresolved output columns as being type text */
1335
139k
  if (pstate->p_resolve_unknowns)
1336
135k
    resolveTargetListUnknowns(pstate, qry->targetList);
1337
1338
139k
  qry->rtable = pstate->p_rtable;
1339
139k
  qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
1340
1341
139k
  qry->hasSubLinks = pstate->p_hasSubLinks;
1342
139k
  qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
1343
139k
  qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
1344
139k
  qry->hasAggs = pstate->p_hasAggs;
1345
1346
139k
  foreach(l, stmt->lockingClause)
1347
4.63k
  {
1348
4.63k
    transformLockingClause(pstate, qry,
1349
4.63k
                 (LockingClause *) lfirst(l), false);
1350
4.63k
  }
1351
1352
139k
  assign_query_collations(pstate, qry);
1353
1354
  /* this must be done after collations, for reliable comparison of exprs */
1355
139k
  if (pstate->p_hasAggs || 
qry->groupClause133k
||
qry->groupingSets133k
||
qry->havingQual133k
)
1356
5.61k
    parseCheckAggregates(pstate, qry);
1357
1358
139k
  return qry;
1359
139k
}
1360
1361
/*
1362
 * transformValuesClause -
1363
 *    transforms a VALUES clause that's being used as a standalone SELECT
1364
 *
1365
 * We build a Query containing a VALUES RTE, rather as if one had written
1366
 *      SELECT * FROM (VALUES ...) AS "*VALUES*"
1367
 */
1368
static Query *
1369
transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1370
1.23k
{
1371
1.23k
  Query    *qry = makeNode(Query);
1372
0
  List     *exprsLists;
1373
1.23k
  List     *coltypes = NIL;
1374
1.23k
  List     *coltypmods = NIL;
1375
1.23k
  List     *colcollations = NIL;
1376
1.23k
  List    **colexprs = NULL;
1377
1.23k
  int     sublist_length = -1;
1378
1.23k
  bool    lateral = false;
1379
1.23k
  RangeTblEntry *rte;
1380
1.23k
  int     rtindex;
1381
1.23k
  ListCell   *lc;
1382
1.23k
  ListCell   *lc2;
1383
1.23k
  int     i;
1384
1385
1.23k
  qry->commandType = CMD_SELECT;
1386
1387
  /* Most SELECT stuff doesn't apply in a VALUES clause */
1388
1.23k
  Assert(stmt->distinctClause == NIL);
1389
1.23k
  Assert(stmt->intoClause == NULL);
1390
1.23k
  Assert(stmt->targetList == NIL);
1391
1.23k
  Assert(stmt->fromClause == NIL);
1392
1.23k
  Assert(stmt->whereClause == NULL);
1393
1.23k
  Assert(stmt->groupClause == NIL);
1394
1.23k
  Assert(stmt->havingClause == NULL);
1395
1.23k
  Assert(stmt->windowClause == NIL);
1396
1.23k
  Assert(stmt->op == SETOP_NONE);
1397
1398
  /* process the WITH clause independently of all else */
1399
1.23k
  if (stmt->withClause)
1400
4
  {
1401
4
    qry->hasRecursive = stmt->withClause->recursive;
1402
4
    qry->cteList = transformWithClause(pstate, stmt->withClause);
1403
4
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1404
4
  }
1405
1406
  /*
1407
   * For each row of VALUES, transform the raw expressions.
1408
   *
1409
   * Note that the intermediate representation we build is column-organized
1410
   * not row-organized.  That simplifies the type and collation processing
1411
   * below.
1412
   */
1413
1.23k
  foreach(lc, stmt->valuesLists)
1414
12.8k
  {
1415
12.8k
    List     *sublist = (List *) lfirst(lc);
1416
1417
    /*
1418
     * Do basic expression transformation (same as a ROW() expr, but here
1419
     * we disallow SetToDefault)
1420
     */
1421
12.8k
    sublist = transformExpressionList(pstate, sublist,
1422
12.8k
                      EXPR_KIND_VALUES, false);
1423
1424
    /*
1425
     * All the sublists must be the same length, *after* transformation
1426
     * (which might expand '*' into multiple items).  The VALUES RTE can't
1427
     * handle anything different.
1428
     */
1429
12.8k
    if (sublist_length < 0)
1430
1.23k
    {
1431
      /* Remember post-transformation length of first sublist */
1432
1.23k
      sublist_length = list_length(sublist);
1433
      /* and allocate array for per-column lists */
1434
1.23k
      colexprs = (List **) palloc0(sublist_length * sizeof(List *));
1435
1.23k
    }
1436
11.6k
    else if (sublist_length != list_length(sublist))
1437
0
    {
1438
0
      ereport(ERROR,
1439
0
          (errcode(ERRCODE_SYNTAX_ERROR),
1440
0
           errmsg("VALUES lists must all be the same length"),
1441
0
           parser_errposition(pstate,
1442
0
                    exprLocation((Node *) sublist))));
1443
0
    }
1444
1445
    /* Build per-column expression lists */
1446
12.8k
    i = 0;
1447
12.8k
    foreach(lc2, sublist)
1448
23.7k
    {
1449
23.7k
      Node     *col = (Node *) lfirst(lc2);
1450
1451
23.7k
      colexprs[i] = lappend(colexprs[i], col);
1452
23.7k
      i++;
1453
23.7k
    }
1454
1455
    /* Release sub-list's cells to save memory */
1456
12.8k
    list_free(sublist);
1457
12.8k
  }
1458
1459
  /*
1460
   * Now resolve the common types of the columns, and coerce everything to
1461
   * those types.  Then identify the common typmod and common collation, if
1462
   * any, of each column.
1463
   *
1464
   * We must do collation processing now because (1) assign_query_collations
1465
   * doesn't process rangetable entries, and (2) we need to label the VALUES
1466
   * RTE with column collations for use in the outer query.  We don't
1467
   * consider conflict of implicit collations to be an error here; instead
1468
   * the column will just show InvalidOid as its collation, and you'll get a
1469
   * failure later if that results in failure to resolve a collation.
1470
   *
1471
   * Note we modify the per-column expression lists in-place.
1472
   */
1473
2.66k
  
for (i = 0; 1.23k
i < sublist_length;
i++1.43k
)
1474
1.43k
  {
1475
1.43k
    Oid     coltype;
1476
1.43k
    int32   coltypmod = -1;
1477
1.43k
    Oid     colcoll;
1478
1.43k
    bool    first = true;
1479
1480
1.43k
    coltype = select_common_type(pstate, colexprs[i], "VALUES", NULL);
1481
1482
1.43k
    foreach(lc, colexprs[i])
1483
23.7k
    {
1484
23.7k
      Node     *col = (Node *) lfirst(lc);
1485
1486
23.7k
      col = coerce_to_common_type(pstate, col, coltype, "VALUES");
1487
23.7k
      lfirst(lc) = (void *) col;
1488
23.7k
      if (first)
1489
1.43k
      {
1490
1.43k
        coltypmod = exprTypmod(col);
1491
1.43k
        first = false;
1492
1.43k
      }
1493
22.3k
      else
1494
22.3k
      {
1495
        /* As soon as we see a non-matching typmod, fall back to -1 */
1496
22.3k
        if (coltypmod >= 0 && 
coltypmod != exprTypmod(col)0
)
1497
0
          coltypmod = -1;
1498
22.3k
      }
1499
23.7k
    }
1500
1501
1.43k
    colcoll = select_common_collation(pstate, colexprs[i], true);
1502
1503
1.43k
    coltypes = lappend_oid(coltypes, coltype);
1504
1.43k
    coltypmods = lappend_int(coltypmods, coltypmod);
1505
1.43k
    colcollations = lappend_oid(colcollations, colcoll);
1506
1.43k
  }
1507
1508
  /*
1509
   * Finally, rearrange the coerced expressions into row-organized lists.
1510
   */
1511
1.23k
  exprsLists = NIL;
1512
1.23k
  foreach(lc, colexprs[0])
1513
12.8k
  {
1514
12.8k
    Node     *col = (Node *) lfirst(lc);
1515
12.8k
    List     *sublist;
1516
1517
12.8k
    sublist = list_make1(col);
1518
12.8k
    exprsLists = lappend(exprsLists, sublist);
1519
12.8k
  }
1520
1.23k
  list_free(colexprs[0]);
1521
1.43k
  for (i = 1; i < sublist_length; 
i++192
)
1522
192
  {
1523
192
    forboth(lc, colexprs[i], lc2, exprsLists)
1524
10.8k
    {
1525
10.8k
      Node     *col = (Node *) lfirst(lc);
1526
10.8k
      List     *sublist = lfirst(lc2);
1527
1528
      /* sublist pointer in exprsLists won't need adjustment */
1529
10.8k
      (void) lappend(sublist, col);
1530
10.8k
    }
1531
192
    list_free(colexprs[i]);
1532
192
  }
1533
1534
  /*
1535
   * Ordinarily there can't be any current-level Vars in the expression
1536
   * lists, because the namespace was empty ... but if we're inside CREATE
1537
   * RULE, then NEW/OLD references might appear.  In that case we have to
1538
   * mark the VALUES RTE as LATERAL.
1539
   */
1540
1.23k
  if (pstate->p_rtable != NIL &&
1541
1.23k
    
contain_vars_of_level((Node *) exprsLists, 0)0
)
1542
0
    lateral = true;
1543
1544
  /*
1545
   * Generate the VALUES RTE
1546
   */
1547
1.23k
  rte = addRangeTableEntryForValues(pstate, exprsLists,
1548
1.23k
                    coltypes, coltypmods, colcollations,
1549
1.23k
                    NULL, lateral, true);
1550
1.23k
  addRTEtoQuery(pstate, rte, true, true, true);
1551
1552
  /* assume new rte is at end */
1553
1.23k
  rtindex = list_length(pstate->p_rtable);
1554
1.23k
  Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
1555
1556
  /*
1557
   * Generate a targetlist as though expanding "*"
1558
   */
1559
1.23k
  Assert(pstate->p_next_resno == 1);
1560
1.23k
  qry->targetList = expandRelAttrs(pstate, rte, rtindex, 0, -1);
1561
1562
  /*
1563
   * The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a
1564
   * VALUES, so cope.
1565
   */
1566
1.23k
  qry->sortClause = transformSortClause(pstate,
1567
1.23k
                      stmt->sortClause,
1568
1.23k
                      &qry->targetList,
1569
1.23k
                      EXPR_KIND_ORDER_BY,
1570
1.23k
                      false /* allow SQL92 rules */ );
1571
1572
1.23k
  qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
1573
1.23k
                      EXPR_KIND_OFFSET, "OFFSET");
1574
1.23k
  qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
1575
1.23k
                       EXPR_KIND_LIMIT, "LIMIT");
1576
1577
1.23k
  if (stmt->lockingClause)
1578
1.23k
    ereport(ERROR,
1579
1.23k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1580
    /*------
1581
      translator: %s is a SQL row locking clause such as FOR UPDATE */
1582
1.23k
         errmsg("%s cannot be applied to VALUES",
1583
1.23k
            LCS_asString(((LockingClause *)
1584
1.23k
                    linitial(stmt->lockingClause))->strength))));
1585
1586
1.23k
  qry->rtable = pstate->p_rtable;
1587
1.23k
  qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1588
1589
1.23k
  qry->hasSubLinks = pstate->p_hasSubLinks;
1590
1591
1.23k
  assign_query_collations(pstate, qry);
1592
1593
1.23k
  return qry;
1594
1.23k
}
1595
1596
/*
1597
 * transformSetOperationStmt -
1598
 *    transforms a set-operations tree
1599
 *
1600
 * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
1601
 * structure to it.  We must transform each leaf SELECT and build up a top-
1602
 * level Query that contains the leaf SELECTs as subqueries in its rangetable.
1603
 * The tree of set operations is converted into the setOperations field of
1604
 * the top-level Query.
1605
 */
1606
static Query *
1607
transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
1608
472
{
1609
472
  Query    *qry = makeNode(Query);
1610
0
  SelectStmt *leftmostSelect;
1611
472
  int     leftmostRTI;
1612
472
  Query    *leftmostQuery;
1613
472
  SetOperationStmt *sostmt;
1614
472
  List     *sortClause;
1615
472
  Node     *limitOffset;
1616
472
  Node     *limitCount;
1617
472
  List     *lockingClause;
1618
472
  WithClause *withClause;
1619
472
  Node     *node;
1620
472
  ListCell   *left_tlist,
1621
472
         *lct,
1622
472
         *lcm,
1623
472
         *lcc,
1624
472
         *l;
1625
472
  List     *targetvars,
1626
472
         *targetnames,
1627
472
         *sv_namespace;
1628
472
  int     sv_rtable_length;
1629
472
  RangeTblEntry *jrte;
1630
472
  int     tllen;
1631
1632
472
  qry->commandType = CMD_SELECT;
1633
1634
  /*
1635
   * Find leftmost leaf SelectStmt.  We currently only need to do this in
1636
   * order to deliver a suitable error message if there's an INTO clause
1637
   * there, implying the set-op tree is in a context that doesn't allow
1638
   * INTO.  (transformSetOperationTree would throw error anyway, but it
1639
   * seems worth the trouble to throw a different error for non-leftmost
1640
   * INTO, so we produce that error in transformSetOperationTree.)
1641
   */
1642
472
  leftmostSelect = stmt->larg;
1643
2.09k
  while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
1644
1.62k
    leftmostSelect = leftmostSelect->larg;
1645
472
  Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
1646
472
       leftmostSelect->larg == NULL);
1647
472
  if (leftmostSelect->intoClause)
1648
472
    ereport(ERROR,
1649
472
        (errcode(ERRCODE_SYNTAX_ERROR),
1650
472
         errmsg("SELECT ... INTO is not allowed here"),
1651
472
         parser_errposition(pstate,
1652
472
                  exprLocation((Node *) leftmostSelect->intoClause))));
1653
1654
  /*
1655
   * We need to extract ORDER BY and other top-level clauses here and not
1656
   * let transformSetOperationTree() see them --- else it'll just recurse
1657
   * right back here!
1658
   */
1659
472
  sortClause = stmt->sortClause;
1660
472
  limitOffset = stmt->limitOffset;
1661
472
  limitCount = stmt->limitCount;
1662
472
  lockingClause = stmt->lockingClause;
1663
472
  withClause = stmt->withClause;
1664
1665
472
  stmt->sortClause = NIL;
1666
472
  stmt->limitOffset = NULL;
1667
472
  stmt->limitCount = NULL;
1668
472
  stmt->lockingClause = NIL;
1669
472
  stmt->withClause = NULL;
1670
1671
  /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
1672
472
  if (lockingClause)
1673
472
    ereport(ERROR,
1674
472
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1675
    /*------
1676
      translator: %s is a SQL row locking clause such as FOR UPDATE */
1677
472
         errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1678
472
            LCS_asString(((LockingClause *)
1679
472
                    linitial(lockingClause))->strength))));
1680
1681
  /* Process the WITH clause independently of all else */
1682
472
  if (withClause)
1683
8
  {
1684
8
    qry->hasRecursive = withClause->recursive;
1685
8
    qry->cteList = transformWithClause(pstate, withClause);
1686
8
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1687
8
  }
1688
1689
  /*
1690
   * Recursively transform the components of the tree.
1691
   */
1692
472
  sostmt = castNode(SetOperationStmt,
1693
472
            transformSetOperationTree(pstate, stmt, true, NULL));
1694
472
  Assert(sostmt);
1695
472
  qry->setOperations = (Node *) sostmt;
1696
1697
  /*
1698
   * Re-find leftmost SELECT (now it's a sub-query in rangetable)
1699
   */
1700
472
  node = sostmt->larg;
1701
2.09k
  while (node && 
IsA2.08k
(node, SetOperationStmt))
1702
1.62k
    node = ((SetOperationStmt *) node)->larg;
1703
472
  Assert(node && IsA(node, RangeTblRef));
1704
472
  leftmostRTI = ((RangeTblRef *) node)->rtindex;
1705
472
  leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
1706
472
  Assert(leftmostQuery != NULL);
1707
1708
  /*
1709
   * Generate dummy targetlist for outer query using column names of
1710
   * leftmost select and common datatypes/collations of topmost set
1711
   * operation.  Also make lists of the dummy vars and their names for use
1712
   * in parsing ORDER BY.
1713
   *
1714
   * Note: we use leftmostRTI as the varno of the dummy variables. It
1715
   * shouldn't matter too much which RT index they have, as long as they
1716
   * have one that corresponds to a real RT entry; else funny things may
1717
   * happen when the tree is mashed by rule rewriting.
1718
   */
1719
472
  qry->targetList = NIL;
1720
472
  targetvars = NIL;
1721
472
  targetnames = NIL;
1722
472
  left_tlist = list_head(leftmostQuery->targetList);
1723
1724
472
  forthree(lct, sostmt->colTypes,
1725
472
       lcm, sostmt->colTypmods,
1726
472
       lcc, sostmt->colCollations)
1727
893
  {
1728
893
    Oid     colType = lfirst_oid(lct);
1729
893
    int32   colTypmod = lfirst_int(lcm);
1730
893
    Oid     colCollation = lfirst_oid(lcc);
1731
893
    TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
1732
893
    char     *colName;
1733
893
    TargetEntry *tle;
1734
893
    Var      *var;
1735
1736
893
    Assert(!lefttle->resjunk);
1737
893
    colName = pstrdup(lefttle->resname);
1738
893
    var = makeVar(leftmostRTI,
1739
893
            lefttle->resno,
1740
893
            colType,
1741
893
            colTypmod,
1742
893
            colCollation,
1743
893
            0);
1744
893
    var->location = exprLocation((Node *) lefttle->expr);
1745
893
    tle = makeTargetEntry((Expr *) var,
1746
893
                (AttrNumber) pstate->p_next_resno++,
1747
893
                colName,
1748
893
                false);
1749
893
    qry->targetList = lappend(qry->targetList, tle);
1750
893
    targetvars = lappend(targetvars, var);
1751
893
    targetnames = lappend(targetnames, makeString(colName));
1752
893
    left_tlist = lnext(left_tlist);
1753
893
  }
1754
1755
  /*
1756
   * As a first step towards supporting sort clauses that are expressions
1757
   * using the output columns, generate a namespace entry that makes the
1758
   * output columns visible.  A Join RTE node is handy for this, since we
1759
   * can easily control the Vars generated upon matches.
1760
   *
1761
   * Note: we don't yet do anything useful with such cases, but at least
1762
   * "ORDER BY upper(foo)" will draw the right error message rather than
1763
   * "foo not found".
1764
   */
1765
472
  sv_rtable_length = list_length(pstate->p_rtable);
1766
1767
472
  jrte = addRangeTableEntryForJoin(pstate,
1768
472
                   targetnames,
1769
472
                   JOIN_INNER,
1770
472
                   targetvars,
1771
472
                   NULL,
1772
472
                   false);
1773
1774
472
  sv_namespace = pstate->p_namespace;
1775
472
  pstate->p_namespace = NIL;
1776
1777
  /* add jrte to column namespace only */
1778
472
  addRTEtoQuery(pstate, jrte, false, false, true);
1779
1780
  /*
1781
   * For now, we don't support resjunk sort clauses on the output of a
1782
   * setOperation tree --- you can only use the SQL92-spec options of
1783
   * selecting an output column by name or number.  Enforce by checking that
1784
   * transformSortClause doesn't add any items to tlist.
1785
   */
1786
472
  tllen = list_length(qry->targetList);
1787
1788
472
  qry->sortClause = transformSortClause(pstate,
1789
472
                      sortClause,
1790
472
                      &qry->targetList,
1791
472
                      EXPR_KIND_ORDER_BY,
1792
472
                      false /* allow SQL92 rules */ );
1793
1794
  /* restore namespace, remove jrte from rtable */
1795
472
  pstate->p_namespace = sv_namespace;
1796
472
  pstate->p_rtable = list_truncate(pstate->p_rtable, sv_rtable_length);
1797
1798
472
  if (tllen != list_length(qry->targetList))
1799
472
    ereport(ERROR,
1800
472
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1801
472
         errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
1802
472
         errdetail("Only result column names can be used, not expressions or functions."),
1803
472
         errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
1804
472
         parser_errposition(pstate,
1805
472
                  exprLocation(list_nth(qry->targetList, tllen)))));
1806
1807
472
  qry->limitOffset = transformLimitClause(pstate, limitOffset,
1808
472
                      EXPR_KIND_OFFSET, "OFFSET");
1809
472
  qry->limitCount = transformLimitClause(pstate, limitCount,
1810
472
                       EXPR_KIND_LIMIT, "LIMIT");
1811
1812
472
  qry->rtable = pstate->p_rtable;
1813
472
  qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1814
1815
472
  qry->hasSubLinks = pstate->p_hasSubLinks;
1816
472
  qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
1817
472
  qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
1818
472
  qry->hasAggs = pstate->p_hasAggs;
1819
1820
472
  foreach(l, lockingClause)
1821
0
  {
1822
0
    transformLockingClause(pstate, qry,
1823
0
                 (LockingClause *) lfirst(l), false);
1824
0
  }
1825
1826
472
  assign_query_collations(pstate, qry);
1827
1828
  /* this must be done after collations, for reliable comparison of exprs */
1829
472
  if (pstate->p_hasAggs || 
qry->groupClause459
||
qry->groupingSets459
||
qry->havingQual459
)
1830
0
    parseCheckAggregates(pstate, qry);
1831
1832
472
  return qry;
1833
472
}
1834
1835
/*
1836
 * transformSetOperationTree
1837
 *    Recursively transform leaves and internal nodes of a set-op tree
1838
 *
1839
 * In addition to returning the transformed node, if targetlist isn't NULL
1840
 * then we return a list of its non-resjunk TargetEntry nodes.  For a leaf
1841
 * set-op node these are the actual targetlist entries; otherwise they are
1842
 * dummy entries created to carry the type, typmod, collation, and location
1843
 * (for error messages) of each output column of the set-op node.  This info
1844
 * is needed only during the internal recursion of this function, so outside
1845
 * callers pass NULL for targetlist.  Note: the reason for passing the
1846
 * actual targetlist entries of a leaf node is so that upper levels can
1847
 * replace UNKNOWN Consts with properly-coerced constants.
1848
 */
1849
static Node *
1850
transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
1851
              bool isTopLevel, List **targetlist)
1852
4.65k
{
1853
4.65k
  bool    isLeaf;
1854
1855
4.65k
  Assert(stmt && IsA(stmt, SelectStmt));
1856
1857
  /* Guard against stack overflow due to overly complex set-expressions */
1858
4.65k
  check_stack_depth();
1859
1860
  /*
1861
   * Validity-check both leaf and internal SELECTs for disallowed ops.
1862
   */
1863
4.65k
  if (stmt->intoClause)
1864
4.65k
    ereport(ERROR,
1865
4.65k
        (errcode(ERRCODE_SYNTAX_ERROR),
1866
4.65k
         errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
1867
4.65k
         parser_errposition(pstate,
1868
4.65k
                  exprLocation((Node *) stmt->intoClause))));
1869
1870
  /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
1871
4.65k
  if (stmt->lockingClause)
1872
4.65k
    ereport(ERROR,
1873
4.65k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1874
    /*------
1875
      translator: %s is a SQL row locking clause such as FOR UPDATE */
1876
4.65k
         errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1877
4.65k
            LCS_asString(((LockingClause *)
1878
4.65k
                    linitial(stmt->lockingClause))->strength))));
1879
1880
  /*
1881
   * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE,
1882
   * or WITH clauses attached, we need to treat it like a leaf node to
1883
   * generate an independent sub-Query tree.  Otherwise, it can be
1884
   * represented by a SetOperationStmt node underneath the parent Query.
1885
   */
1886
4.65k
  if (stmt->op == SETOP_NONE)
1887
2.55k
  {
1888
2.55k
    Assert(stmt->larg == NULL && stmt->rarg == NULL);
1889
2.55k
    isLeaf = true;
1890
2.55k
  }
1891
2.10k
  else
1892
2.10k
  {
1893
2.10k
    Assert(stmt->larg != NULL && stmt->rarg != NULL);
1894
2.10k
    if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
1895
2.10k
      stmt->lockingClause || stmt->withClause)
1896
5
      isLeaf = true;
1897
2.09k
    else
1898
2.09k
      isLeaf = false;
1899
2.10k
  }
1900
1901
4.65k
  if (isLeaf)
1902
2.56k
  {
1903
    /* Process leaf SELECT */
1904
2.56k
    Query    *selectQuery;
1905
2.56k
    char    selectName[32];
1906
2.56k
    RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY;
1907
2.56k
    RangeTblRef *rtr;
1908
2.56k
    ListCell   *tl;
1909
1910
    /*
1911
     * Transform SelectStmt into a Query.
1912
     *
1913
     * This works the same as SELECT transformation normally would, except
1914
     * that we prevent resolving unknown-type outputs as TEXT.  This does
1915
     * not change the subquery's semantics since if the column type
1916
     * matters semantically, it would have been resolved to something else
1917
     * anyway.  Doing this lets us resolve such outputs using
1918
     * select_common_type(), below.
1919
     *
1920
     * Note: previously transformed sub-queries don't affect the parsing
1921
     * of this sub-query, because they are not in the toplevel pstate's
1922
     * namespace list.
1923
     */
1924
2.56k
    selectQuery = parse_sub_analyze((Node *) stmt, pstate,
1925
2.56k
                    NULL, false, false);
1926
1927
    /*
1928
     * Check for bogus references to Vars on the current query level (but
1929
     * upper-level references are okay). Normally this can't happen
1930
     * because the namespace will be empty, but it could happen if we are
1931
     * inside a rule.
1932
     */
1933
2.56k
    if (pstate->p_namespace)
1934
0
    {
1935
0
      if (contain_vars_of_level((Node *) selectQuery, 1))
1936
0
        ereport(ERROR,
1937
0
            (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1938
0
             errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
1939
0
             parser_errposition(pstate,
1940
0
                      locate_var_of_level((Node *) selectQuery, 1))));
1941
0
    }
1942
1943
    /*
1944
     * Extract a list of the non-junk TLEs for upper-level processing.
1945
     */
1946
2.56k
    if (targetlist)
1947
2.55k
    {
1948
2.55k
      *targetlist = NIL;
1949
2.55k
      foreach(tl, selectQuery->targetList)
1950
5.32k
      {
1951
5.32k
        TargetEntry *tle = (TargetEntry *) lfirst(tl);
1952
1953
5.32k
        if (!tle->resjunk)
1954
5.32k
          *targetlist = lappend(*targetlist, tle);
1955
5.32k
      }
1956
2.55k
    }
1957
1958
    /*
1959
     * Make the leaf query be a subquery in the top-level rangetable.
1960
     */
1961
2.56k
    snprintf(selectName, sizeof(selectName), "*SELECT* %d",
1962
2.56k
         list_length(pstate->p_rtable) + 1);
1963
2.56k
    rte = addRangeTableEntryForSubquery(pstate,
1964
2.56k
                      selectQuery,
1965
2.56k
                      makeAlias(selectName, NIL),
1966
2.56k
                      false,
1967
2.56k
                      false);
1968
1969
    /*
1970
     * Return a RangeTblRef to replace the SelectStmt in the set-op tree.
1971
     */
1972
2.56k
    rtr = makeNode(RangeTblRef);
1973
    /* assume new rte is at end */
1974
0
    rtr->rtindex = list_length(pstate->p_rtable);
1975
2.56k
    Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
1976
2.56k
    return (Node *) rtr;
1977
2.56k
  }
1978
2.09k
  else
1979
2.09k
  {
1980
    /* Process an internal node (set operation node) */
1981
2.09k
    SetOperationStmt *op = makeNode(SetOperationStmt);
1982
0
    List     *ltargetlist;
1983
2.09k
    List     *rtargetlist;
1984
2.09k
    ListCell   *ltl;
1985
2.09k
    ListCell   *rtl;
1986
2.09k
    const char *context;
1987
1988
2.09k
    context = (stmt->op == SETOP_UNION ? 
"UNION"2.07k
:
1989
2.09k
           
(25
stmt->op == SETOP_INTERSECT25
?
"INTERSECT"7
:
1990
25
          
"EXCEPT"18
));
1991
1992
2.09k
    op->op = stmt->op;
1993
2.09k
    op->all = stmt->all;
1994
1995
    /*
1996
     * Recursively transform the left child node.
1997
     */
1998
2.09k
    op->larg = transformSetOperationTree(pstate, stmt->larg,
1999
2.09k
                       false,
2000
2.09k
                       &ltargetlist);
2001
2002
    /*
2003
     * If we are processing a recursive union query, now is the time to
2004
     * examine the non-recursive term's output columns and mark the
2005
     * containing CTE as having those result columns.  We should do this
2006
     * only at the topmost setop of the CTE, of course.
2007
     */
2008
2.09k
    if (isTopLevel &&
2009
2.09k
      
pstate->p_parent_cte469
&&
2010
2.09k
      
pstate->p_parent_cte->cterecursive60
)
2011
51
      determineRecursiveColTypes(pstate, op->larg, ltargetlist);
2012
2013
    /*
2014
     * Recursively transform the right child node.
2015
     */
2016
2.09k
    op->rarg = transformSetOperationTree(pstate, stmt->rarg,
2017
2.09k
                       false,
2018
2.09k
                       &rtargetlist);
2019
2020
    /*
2021
     * Verify that the two children have the same number of non-junk
2022
     * columns, and determine the types of the merged output columns.
2023
     */
2024
2.09k
    if (list_length(ltargetlist) != list_length(rtargetlist))
2025
2.09k
      ereport(ERROR,
2026
2.09k
          (errcode(ERRCODE_SYNTAX_ERROR),
2027
2.09k
           errmsg("each %s query must have the same number of columns",
2028
2.09k
              context),
2029
2.09k
           parser_errposition(pstate,
2030
2.09k
                    exprLocation((Node *) rtargetlist))));
2031
2032
2.09k
    if (targetlist)
2033
1.62k
      *targetlist = NIL;
2034
2.09k
    op->colTypes = NIL;
2035
2.09k
    op->colTypmods = NIL;
2036
2.09k
    op->colCollations = NIL;
2037
2.09k
    op->groupClauses = NIL;
2038
2.09k
    forboth(ltl, ltargetlist, rtl, rtargetlist)
2039
4.41k
    {
2040
4.41k
      TargetEntry *ltle = (TargetEntry *) lfirst(ltl);
2041
4.41k
      TargetEntry *rtle = (TargetEntry *) lfirst(rtl);
2042
4.41k
      Node     *lcolnode = (Node *) ltle->expr;
2043
4.41k
      Node     *rcolnode = (Node *) rtle->expr;
2044
4.41k
      Oid     lcoltype = exprType(lcolnode);
2045
4.41k
      Oid     rcoltype = exprType(rcolnode);
2046
4.41k
      int32   lcoltypmod = exprTypmod(lcolnode);
2047
4.41k
      int32   rcoltypmod = exprTypmod(rcolnode);
2048
4.41k
      Node     *bestexpr;
2049
4.41k
      int     bestlocation;
2050
4.41k
      Oid     rescoltype;
2051
4.41k
      int32   rescoltypmod;
2052
4.41k
      Oid     rescolcoll;
2053
2054
      /* select common type, same as CASE et al */
2055
4.41k
      rescoltype = select_common_type(pstate,
2056
4.41k
                      list_make2(lcolnode, rcolnode),
2057
4.41k
                      context,
2058
4.41k
                      &bestexpr);
2059
4.41k
      bestlocation = exprLocation(bestexpr);
2060
      /* if same type and same typmod, use typmod; else default */
2061
4.41k
      if (lcoltype == rcoltype && 
lcoltypmod == rcoltypmod4.35k
)
2062
4.35k
        rescoltypmod = lcoltypmod;
2063
59
      else
2064
59
        rescoltypmod = -1;
2065
2066
      /*
2067
       * Verify the coercions are actually possible.  If not, we'd fail
2068
       * later anyway, but we want to fail now while we have sufficient
2069
       * context to produce an error cursor position.
2070
       *
2071
       * For all non-UNKNOWN-type cases, we verify coercibility but we
2072
       * don't modify the child's expression, for fear of changing the
2073
       * child query's semantics.
2074
       *
2075
       * If a child expression is an UNKNOWN-type Const or Param, we
2076
       * want to replace it with the coerced expression.  This can only
2077
       * happen when the child is a leaf set-op node.  It's safe to
2078
       * replace the expression because if the child query's semantics
2079
       * depended on the type of this output column, it'd have already
2080
       * coerced the UNKNOWN to something else.  We want to do this
2081
       * because (a) we want to verify that a Const is valid for the
2082
       * target type, or resolve the actual type of an UNKNOWN Param,
2083
       * and (b) we want to avoid unnecessary discrepancies between the
2084
       * output type of the child query and the resolved target type.
2085
       * Such a discrepancy would disable optimization in the planner.
2086
       *
2087
       * If it's some other UNKNOWN-type node, eg a Var, we do nothing
2088
       * (knowing that coerce_to_common_type would fail).  The planner
2089
       * is sometimes able to fold an UNKNOWN Var to a constant before
2090
       * it has to coerce the type, so failing now would just break
2091
       * cases that might work.
2092
       */
2093
4.41k
      if (lcoltype != UNKNOWNOID)
2094
4.40k
        lcolnode = coerce_to_common_type(pstate, lcolnode,
2095
4.40k
                         rescoltype, context);
2096
9
      else if (IsA(lcolnode, Const) ||
2097
9
           
IsA0
(lcolnode, Param))
2098
9
      {
2099
9
        lcolnode = coerce_to_common_type(pstate, lcolnode,
2100
9
                         rescoltype, context);
2101
9
        ltle->expr = (Expr *) lcolnode;
2102
9
      }
2103
2104
4.41k
      if (rcoltype != UNKNOWNOID)
2105
4.36k
        rcolnode = coerce_to_common_type(pstate, rcolnode,
2106
4.36k
                         rescoltype, context);
2107
48
      else if (IsA(rcolnode, Const) ||
2108
48
           
IsA0
(rcolnode, Param))
2109
48
      {
2110
48
        rcolnode = coerce_to_common_type(pstate, rcolnode,
2111
48
                         rescoltype, context);
2112
48
        rtle->expr = (Expr *) rcolnode;
2113
48
      }
2114
2115
      /*
2116
       * Select common collation.  A common collation is required for
2117
       * all set operators except UNION ALL; see SQL:2008 7.13 <query
2118
       * expression> Syntax Rule 15c.  (If we fail to identify a common
2119
       * collation for a UNION ALL column, the curCollations element
2120
       * will be set to InvalidOid, which may result in a runtime error
2121
       * if something at a higher query level wants to use the column's
2122
       * collation.)
2123
       */
2124
4.41k
      rescolcoll = select_common_collation(pstate,
2125
4.41k
                         list_make2(lcolnode, rcolnode),
2126
4.41k
                         (op->op == SETOP_UNION && 
op->all4.37k
));
2127
2128
      /* emit results */
2129
4.41k
      op->colTypes = lappend_oid(op->colTypes, rescoltype);
2130
4.41k
      op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
2131
4.41k
      op->colCollations = lappend_oid(op->colCollations, rescolcoll);
2132
2133
      /*
2134
       * For all cases except UNION ALL, identify the grouping operators
2135
       * (and, if available, sorting operators) that will be used to
2136
       * eliminate duplicates.
2137
       */
2138
4.41k
      if (op->op != SETOP_UNION || 
!op->all4.37k
)
2139
3.35k
      {
2140
3.35k
        SortGroupClause *grpcl = makeNode(SortGroupClause);
2141
0
        Oid     sortop;
2142
3.35k
        Oid     eqop;
2143
3.35k
        bool    hashable;
2144
3.35k
        ParseCallbackState pcbstate;
2145
2146
3.35k
        setup_parser_errposition_callback(&pcbstate, pstate,
2147
3.35k
                          bestlocation);
2148
2149
        /* determine the eqop and optional sortop */
2150
3.35k
        get_sort_group_operators(rescoltype,
2151
3.35k
                     false, true, false,
2152
3.35k
                     &sortop, &eqop, NULL,
2153
3.35k
                     &hashable);
2154
2155
3.35k
        cancel_parser_errposition_callback(&pcbstate);
2156
2157
        /* we don't have a tlist yet, so can't assign sortgrouprefs */
2158
3.35k
        grpcl->tleSortGroupRef = 0;
2159
3.35k
        grpcl->eqop = eqop;
2160
3.35k
        grpcl->sortop = sortop;
2161
3.35k
        grpcl->nulls_first = false; /* OK with or without sortop */
2162
3.35k
        grpcl->hashable = hashable;
2163
2164
3.35k
        op->groupClauses = lappend(op->groupClauses, grpcl);
2165
3.35k
      }
2166
2167
      /*
2168
       * Construct a dummy tlist entry to return.  We use a SetToDefault
2169
       * node for the expression, since it carries exactly the fields
2170
       * needed, but any other expression node type would do as well.
2171
       */
2172
4.41k
      if (targetlist)
2173
3.50k
      {
2174
3.50k
        SetToDefault *rescolnode = makeNode(SetToDefault);
2175
0
        TargetEntry *restle;
2176
2177
3.50k
        rescolnode->typeId = rescoltype;
2178
3.50k
        rescolnode->typeMod = rescoltypmod;
2179
3.50k
        rescolnode->collation = rescolcoll;
2180
3.50k
        rescolnode->location = bestlocation;
2181
3.50k
        restle = makeTargetEntry((Expr *) rescolnode,
2182
3.50k
                     0, /* no need to set resno */
2183
3.50k
                     NULL,
2184
3.50k
                     false);
2185
3.50k
        *targetlist = lappend(*targetlist, restle);
2186
3.50k
      }
2187
4.41k
    }
2188
2189
2.09k
    return (Node *) op;
2190
2.09k
  }
2191
4.65k
}
2192
2193
/*
2194
 * Process the outputs of the non-recursive term of a recursive union
2195
 * to set up the parent CTE's columns
2196
 */
2197
static void
2198
determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
2199
51
{
2200
51
  Node     *node;
2201
51
  int     leftmostRTI;
2202
51
  Query    *leftmostQuery;
2203
51
  List     *targetList;
2204
51
  ListCell   *left_tlist;
2205
51
  ListCell   *nrtl;
2206
51
  int     next_resno;
2207
2208
  /*
2209
   * Find leftmost leaf SELECT
2210
   */
2211
51
  node = larg;
2212
51
  while (node && IsA(node, SetOperationStmt))
2213
0
    node = ((SetOperationStmt *) node)->larg;
2214
51
  Assert(node && IsA(node, RangeTblRef));
2215
51
  leftmostRTI = ((RangeTblRef *) node)->rtindex;
2216
51
  leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
2217
51
  Assert(leftmostQuery != NULL);
2218
2219
  /*
2220
   * Generate dummy targetlist using column names of leftmost select and
2221
   * dummy result expressions of the non-recursive term.
2222
   */
2223
51
  targetList = NIL;
2224
51
  left_tlist = list_head(leftmostQuery->targetList);
2225
51
  next_resno = 1;
2226
2227
51
  foreach(nrtl, nrtargetlist)
2228
94
  {
2229
94
    TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl);
2230
94
    TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
2231
94
    char     *colName;
2232
94
    TargetEntry *tle;
2233
2234
94
    Assert(!lefttle->resjunk);
2235
94
    colName = pstrdup(lefttle->resname);
2236
94
    tle = makeTargetEntry(nrtle->expr,
2237
94
                next_resno++,
2238
94
                colName,
2239
94
                false);
2240
94
    targetList = lappend(targetList, tle);
2241
94
    left_tlist = lnext(left_tlist);
2242
94
  }
2243
2244
  /* Now build CTE's output column info using dummy targetlist */
2245
51
  analyzeCTETargetList(pstate, pstate->p_parent_cte, targetList);
2246
51
}
2247
2248
2249
/*
2250
 * transformUpdateStmt -
2251
 *    transforms an update statement
2252
 */
2253
static Query *
2254
transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
2255
29.3k
{
2256
29.3k
  Query    *qry = makeNode(Query);
2257
0
  ParseNamespaceItem *nsitem;
2258
29.3k
  Node     *qual;
2259
2260
29.3k
  qry->commandType = CMD_UPDATE;
2261
29.3k
  pstate->p_is_insert = false;
2262
2263
  /* process the WITH clause independently of all else */
2264
29.3k
  if (stmt->withClause)
2265
712
  {
2266
712
    qry->hasRecursive = stmt->withClause->recursive;
2267
712
    qry->cteList = transformWithClause(pstate, stmt->withClause);
2268
712
    qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
2269
712
  }
2270
2271
29.3k
  qry->resultRelation = setTargetTable(pstate, stmt->relation,
2272
29.3k
                     stmt->relation->inh,
2273
29.3k
                     true,
2274
29.3k
                     ACL_UPDATE);
2275
2276
  /* grab the namespace item made by setTargetTable */
2277
29.3k
  nsitem = (ParseNamespaceItem *) llast(pstate->p_namespace);
2278
2279
  /* subqueries in FROM cannot access the result relation */
2280
29.3k
  nsitem->p_lateral_only = true;
2281
29.3k
  nsitem->p_lateral_ok = false;
2282
2283
  /*
2284
   * the FROM clause is non-standard SQL syntax. We used to be able to do
2285
   * this with REPLACE in POSTQUEL so we keep the feature.
2286
   */
2287
29.3k
  transformFromClause(pstate, stmt->fromClause);
2288
2289
  /* remaining clauses can reference the result relation normally */
2290
29.3k
  nsitem->p_lateral_only = false;
2291
29.3k
  nsitem->p_lateral_ok = true;
2292
2293
29.3k
  qual = transformWhereClause(pstate, stmt->whereClause,
2294
29.3k
                EXPR_KIND_WHERE, "WHERE");
2295
2296
29.3k
  qry->returningList = transformReturningList(pstate, stmt->returningList);
2297
2298
  /*
2299
   * Now we are done with SELECT-like processing, and can get on with
2300
   * transforming the target list to match the UPDATE target columns.
2301
   */
2302
29.3k
  qry->targetList = transformUpdateTargetList(pstate, stmt->targetList);
2303
2304
29.3k
  qry->rtable = pstate->p_rtable;
2305
29.3k
  qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
2306
2307
29.3k
  qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
2308
29.3k
  qry->hasSubLinks = pstate->p_hasSubLinks;
2309
2310
29.3k
  assign_query_collations(pstate, qry);
2311
2312
29.3k
  return qry;
2313
29.3k
}
2314
2315
/*
2316
 * transformUpdateTargetList -
2317
 *  handle SET clause in UPDATE/INSERT ... ON CONFLICT UPDATE
2318
 */
2319
static List *
2320
transformUpdateTargetList(ParseState *pstate, List *origTlist)
2321
36.7k
{
2322
36.7k
  List     *tlist = NIL;
2323
36.7k
  RangeTblEntry *target_rte;
2324
36.7k
  ListCell   *orig_tl;
2325
36.7k
  ListCell   *tl;
2326
2327
36.7k
  tlist = transformTargetList(pstate, origTlist,
2328
36.7k
                EXPR_KIND_UPDATE_SOURCE);
2329
2330
  /* Prepare to assign non-conflicting resnos to resjunk attributes */
2331
36.7k
  if (pstate->p_next_resno <= RelationGetNumberOfAttributes(pstate->p_target_relation))
2332
36.6k
    pstate->p_next_resno = RelationGetNumberOfAttributes(pstate->p_target_relation) + 1;
2333
2334
  /* Prepare non-junk columns for assignment to target table */
2335
36.7k
  target_rte = pstate->p_target_rangetblentry;
2336
36.7k
  orig_tl = list_head(origTlist);
2337
2338
36.7k
  foreach(tl, tlist)
2339
37.4k
  {
2340
37.4k
    TargetEntry *tle = (TargetEntry *) lfirst(tl);
2341
37.4k
    ResTarget  *origTarget;
2342
37.4k
    int     attrno;
2343
2344
37.4k
    if (tle->resjunk)
2345
2
    {
2346
      /*
2347
       * Resjunk nodes need no additional processing, but be sure they
2348
       * have resnos that do not match any target columns; else rewriter
2349
       * or planner might get confused.  They don't need a resname
2350
       * either.
2351
       */
2352
2
      tle->resno = (AttrNumber) pstate->p_next_resno++;
2353
2
      tle->resname = NULL;
2354
2
      continue;
2355
2
    }
2356
37.4k
    if (orig_tl == NULL)
2357
0
      elog(ERROR, "UPDATE target count mismatch --- internal error");
2358
37.4k
    origTarget = lfirst_node(ResTarget, orig_tl);
2359
2360
37.4k
    attrno = attnameAttNum(pstate->p_target_relation,
2361
37.4k
                 origTarget->name, true);
2362
37.4k
    if (attrno == InvalidAttrNumber)
2363
37.4k
      ereport(ERROR,
2364
37.4k
          (errcode(ERRCODE_UNDEFINED_COLUMN),
2365
37.4k
           errmsg("column \"%s\" of relation \"%s\" does not exist",
2366
37.4k
              origTarget->name,
2367
37.4k
              RelationGetRelationName(pstate->p_target_relation)),
2368
37.4k
           parser_errposition(pstate, origTarget->location)));
2369
2370
37.4k
    updateTargetListEntry(pstate, tle, origTarget->name,
2371
37.4k
                attrno,
2372
37.4k
                origTarget->indirection,
2373
37.4k
                origTarget->location);
2374
2375
    /* Mark the target column as requiring update permissions */
2376
37.4k
    target_rte->updatedCols = bms_add_member(target_rte->updatedCols,
2377
37.4k
                         attrno - YBGetFirstLowInvalidAttributeNumber(pstate->p_target_relation));
2378
2379
37.4k
    orig_tl = lnext(orig_tl);
2380
37.4k
  }
2381
36.7k
  if (orig_tl != NULL)
2382
0
    elog(ERROR, "UPDATE target count mismatch --- internal error");
2383
2384
36.7k
  return tlist;
2385
36.7k
}
2386
2387
/*
2388
 * transformReturningList -
2389
 *  handle a RETURNING clause in INSERT/UPDATE/DELETE
2390
 */
2391
static List *
2392
transformReturningList(ParseState *pstate, List *returningList)
2393
33.9k
{
2394
33.9k
  List     *rlist;
2395
33.9k
  int     save_next_resno;
2396
2397
33.9k
  if (returningList == NIL)
2398
31.6k
    return NIL;        /* nothing to do */
2399
2400
  /*
2401
   * We need to assign resnos starting at one in the RETURNING list. Save
2402
   * and restore the main tlist's value of p_next_resno, just in case
2403
   * someone looks at it later (probably won't happen).
2404
   */
2405
2.27k
  save_next_resno = pstate->p_next_resno;
2406
2.27k
  pstate->p_next_resno = 1;
2407
2408
  /* transform RETURNING identically to a SELECT targetlist */
2409
2.27k
  rlist = transformTargetList(pstate, returningList, EXPR_KIND_RETURNING);
2410
2411
  /*
2412
   * Complain if the nonempty tlist expanded to nothing (which is possible
2413
   * if it contains only a star-expansion of a zero-column table).  If we
2414
   * allow this, the parsed Query will look like it didn't have RETURNING,
2415
   * with results that would probably surprise the user.
2416
   */
2417
2.27k
  if (rlist == NIL)
2418
2.27k
    ereport(ERROR,
2419
2.27k
        (errcode(ERRCODE_SYNTAX_ERROR),
2420
2.27k
         errmsg("RETURNING must have at least one column"),
2421
2.27k
         parser_errposition(pstate,
2422
2.27k
                  exprLocation(linitial(returningList)))));
2423
2424
  /* mark column origins */
2425
2.27k
  markTargetListOrigins(pstate, rlist);
2426
2427
  /* resolve any still-unresolved output columns as being type text */
2428
2.27k
  if (pstate->p_resolve_unknowns)
2429
2.26k
    resolveTargetListUnknowns(pstate, rlist);
2430
2431
  /* restore state */
2432
2.27k
  pstate->p_next_resno = save_next_resno;
2433
2434
2.27k
  return rlist;
2435
2.27k
}
2436
2437
2438
/*
2439
 * transformDeclareCursorStmt -
2440
 *  transform a DECLARE CURSOR Statement
2441
 *
2442
 * DECLARE CURSOR is like other utility statements in that we emit it as a
2443
 * CMD_UTILITY Query node; however, we must first transform the contained
2444
 * query.  We used to postpone that until execution, but it's really necessary
2445
 * to do it during the normal parse analysis phase to ensure that side effects
2446
 * of parser hooks happen at the expected time.
2447
 */
2448
static Query *
2449
transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
2450
1.55k
{
2451
1.55k
  Query    *result;
2452
1.55k
  Query    *query;
2453
2454
  /*
2455
   * Don't allow both SCROLL and NO SCROLL to be specified
2456
   */
2457
1.55k
  if ((stmt->options & CURSOR_OPT_SCROLL) &&
2458
1.55k
    
(stmt->options & 31
CURSOR_OPT_NO_SCROLL31
))
2459
1.55k
    ereport(ERROR,
2460
1.55k
        (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
2461
1.55k
         errmsg("cannot specify both SCROLL and NO SCROLL")));
2462
2463
  /* Transform contained query, not allowing SELECT INTO */
2464
1.55k
  query = transformStmt(pstate, stmt->query);
2465
1.55k
  stmt->query = (Node *) query;
2466
2467
  /* Grammar should not have allowed anything but SELECT */
2468
1.55k
  if (!IsA(query, Query) ||
2469
1.55k
    
query->commandType != CMD_SELECT1.54k
)
2470
0
    elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
2471
2472
  /*
2473
   * We also disallow data-modifying WITH in a cursor.  (This could be
2474
   * allowed, but the semantics of when the updates occur might be
2475
   * surprising.)
2476
   */
2477
1.55k
  if (query->hasModifyingCTE)
2478
1.55k
    ereport(ERROR,
2479
1.55k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2480
1.55k
         errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH")));
2481
2482
  /* FOR UPDATE and WITH HOLD are not compatible */
2483
1.55k
  if (query->rowMarks != NIL && 
(stmt->options & 9
CURSOR_OPT_HOLD9
))
2484
1.55k
    ereport(ERROR,
2485
1.55k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2486
    /*------
2487
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2488
1.55k
         errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported",
2489
1.55k
            LCS_asString(((RowMarkClause *)
2490
1.55k
                    linitial(query->rowMarks))->strength)),
2491
1.55k
         errdetail("Holdable cursors must be READ ONLY.")));
2492
2493
  /* FOR UPDATE and SCROLL are not compatible */
2494
1.55k
  if (query->rowMarks != NIL && 
(stmt->options & 9
CURSOR_OPT_SCROLL9
))
2495
1.55k
    ereport(ERROR,
2496
1.55k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2497
    /*------
2498
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2499
1.55k
         errmsg("DECLARE SCROLL CURSOR ... %s is not supported",
2500
1.55k
            LCS_asString(((RowMarkClause *)
2501
1.55k
                    linitial(query->rowMarks))->strength)),
2502
1.55k
         errdetail("Scrollable cursors must be READ ONLY.")));
2503
2504
  /* FOR UPDATE and INSENSITIVE are not compatible */
2505
1.55k
  if (query->rowMarks != NIL && 
(stmt->options & 9
CURSOR_OPT_INSENSITIVE9
))
2506
1.55k
    ereport(ERROR,
2507
1.55k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2508
    /*------
2509
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2510
1.55k
         errmsg("DECLARE INSENSITIVE CURSOR ... %s is not supported",
2511
1.55k
            LCS_asString(((RowMarkClause *)
2512
1.55k
                    linitial(query->rowMarks))->strength)),
2513
1.55k
         errdetail("Insensitive cursors must be READ ONLY.")));
2514
2515
  /* represent the command as a utility Query */
2516
1.55k
  result = makeNode(Query);
2517
0
  result->commandType = CMD_UTILITY;
2518
1.55k
  result->utilityStmt = (Node *) stmt;
2519
2520
1.55k
  return result;
2521
1.55k
}
2522
2523
2524
/*
2525
 * transformExplainStmt -
2526
 *  transform an EXPLAIN Statement
2527
 *
2528
 * EXPLAIN is like other utility statements in that we emit it as a
2529
 * CMD_UTILITY Query node; however, we must first transform the contained
2530
 * query.  We used to postpone that until execution, but it's really necessary
2531
 * to do it during the normal parse analysis phase to ensure that side effects
2532
 * of parser hooks happen at the expected time.
2533
 */
2534
static Query *
2535
transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
2536
2.73k
{
2537
2.73k
  Query    *result;
2538
2539
  /* transform contained query, allowing SELECT INTO */
2540
2.73k
  stmt->query = (Node *) transformOptionalSelectInto(pstate, stmt->query);
2541
2542
  /* represent the command as a utility Query */
2543
2.73k
  result = makeNode(Query);
2544
0
  result->commandType = CMD_UTILITY;
2545
2.73k
  result->utilityStmt = (Node *) stmt;
2546
2547
2.73k
  return result;
2548
2.73k
}
2549
2550
2551
/*
2552
 * transformCreateTableAsStmt -
2553
 *  transform a CREATE TABLE AS, SELECT ... INTO, or CREATE MATERIALIZED VIEW
2554
 *  Statement
2555
 *
2556
 * As with DECLARE CURSOR and EXPLAIN, transform the contained statement now.
2557
 */
2558
static Query *
2559
transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
2560
110
{
2561
110
  Query    *result;
2562
110
  Query    *query;
2563
2564
  /* transform contained query, not allowing SELECT INTO */
2565
110
  query = transformStmt(pstate, stmt->query);
2566
110
  stmt->query = (Node *) query;
2567
2568
  /* additional work needed for CREATE MATERIALIZED VIEW */
2569
110
  if (stmt->relkind == OBJECT_MATVIEW)
2570
44
  {
2571
    /*
2572
     * Prohibit a data-modifying CTE in the query used to create a
2573
     * materialized view. It's not sufficiently clear what the user would
2574
     * want to happen if the MV is refreshed or incrementally maintained.
2575
     */
2576
44
    if (query->hasModifyingCTE)
2577
44
      ereport(ERROR,
2578
44
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2579
44
           errmsg("materialized views must not use data-modifying statements in WITH")));
2580
2581
    /*
2582
     * Check whether any temporary database objects are used in the
2583
     * creation query. It would be hard to refresh data or incrementally
2584
     * maintain it if a source disappeared.
2585
     */
2586
44
    if (isQueryUsingTempRelation(query))
2587
44
      ereport(ERROR,
2588
44
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2589
44
           errmsg("materialized views must not use temporary tables or views")));
2590
2591
    /*
2592
     * A materialized view would either need to save parameters for use in
2593
     * maintaining/loading the data or prohibit them entirely.  The latter
2594
     * seems safer and more sane.
2595
     */
2596
44
    if (query_contains_extern_params(query))
2597
44
      ereport(ERROR,
2598
44
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2599
44
           errmsg("materialized views may not be defined using bound parameters")));
2600
2601
    /*
2602
     * For now, we disallow unlogged materialized views, because it seems
2603
     * like a bad idea for them to just go to empty after a crash. (If we
2604
     * could mark them as unpopulated, that would be better, but that
2605
     * requires catalog changes which crash recovery can't presently
2606
     * handle.)
2607
     */
2608
44
    if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED)
2609
44
      ereport(ERROR,
2610
44
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2611
44
           errmsg("materialized views cannot be UNLOGGED")));
2612
2613
    /*
2614
     * At runtime, we'll need a copy of the parsed-but-not-rewritten Query
2615
     * for purposes of creating the view's ON SELECT rule.  We stash that
2616
     * in the IntoClause because that's where intorel_startup() can
2617
     * conveniently get it from.
2618
     */
2619
44
    stmt->into->viewQuery = (Node *) copyObject(query);
2620
44
  }
2621
2622
  /* represent the command as a utility Query */
2623
110
  result = makeNode(Query);
2624
0
  result->commandType = CMD_UTILITY;
2625
110
  result->utilityStmt = (Node *) stmt;
2626
2627
110
  return result;
2628
110
}
2629
2630
/*
2631
 * transform a CallStmt
2632
 *
2633
 * We need to do parse analysis on the procedure call and its arguments.
2634
 */
2635
static Query *
2636
transformCallStmt(ParseState *pstate, CallStmt *stmt)
2637
426
{
2638
426
  List     *targs;
2639
426
  ListCell   *lc;
2640
426
  Node     *node;
2641
426
  Query    *result;
2642
2643
426
  targs = NIL;
2644
426
  foreach(lc, stmt->funccall->args)
2645
422
  {
2646
422
    targs = lappend(targs, transformExpr(pstate,
2647
422
                       (Node *) lfirst(lc),
2648
422
                       EXPR_KIND_CALL_ARGUMENT));
2649
422
  }
2650
2651
426
  node = ParseFuncOrColumn(pstate,
2652
426
               stmt->funccall->funcname,
2653
426
               targs,
2654
426
               pstate->p_last_srf,
2655
426
               stmt->funccall,
2656
426
               true,
2657
426
               stmt->funccall->location);
2658
2659
426
  assign_expr_collations(pstate, node);
2660
2661
426
  stmt->funcexpr = castNode(FuncExpr, node);
2662
2663
426
  result = makeNode(Query);
2664
0
  result->commandType = CMD_UTILITY;
2665
426
  result->utilityStmt = (Node *) stmt;
2666
2667
426
  return result;
2668
426
}
2669
2670
/*
2671
 * Produce a string representation of a LockClauseStrength value.
2672
 * This should only be applied to valid values (not LCS_NONE).
2673
 */
2674
const char *
2675
LCS_asString(LockClauseStrength strength)
2676
3
{
2677
3
  switch (strength)
2678
3
  {
2679
0
    case LCS_NONE:
2680
0
      Assert(false);
2681
0
      break;
2682
0
    case LCS_FORKEYSHARE:
2683
0
      return "FOR KEY SHARE";
2684
0
    case LCS_FORSHARE:
2685
0
      return "FOR SHARE";
2686
0
    case LCS_FORNOKEYUPDATE:
2687
0
      return "FOR NO KEY UPDATE";
2688
3
    case LCS_FORUPDATE:
2689
3
      return "FOR UPDATE";
2690
3
  }
2691
0
  return "FOR some";     /* shouldn't happen */
2692
3
}
2693
2694
/*
2695
 * Check for features that are not supported with FOR [KEY] UPDATE/SHARE.
2696
 *
2697
 * exported so planner can check again after rewriting, query pullup, etc
2698
 */
2699
void
2700
CheckSelectLocking(Query *qry, LockClauseStrength strength)
2701
9.40k
{
2702
9.40k
  Assert(strength != LCS_NONE); /* else caller error */
2703
2704
9.40k
  if (qry->setOperations)
2705
9.40k
    ereport(ERROR,
2706
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2707
    /*------
2708
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2709
9.40k
         errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
2710
9.40k
            LCS_asString(strength))));
2711
9.40k
  if (qry->distinctClause != NIL)
2712
9.40k
    ereport(ERROR,
2713
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2714
    /*------
2715
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2716
9.40k
         errmsg("%s is not allowed with DISTINCT clause",
2717
9.40k
            LCS_asString(strength))));
2718
9.40k
  if (qry->groupClause != NIL || qry->groupingSets != NIL)
2719
9.40k
    ereport(ERROR,
2720
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2721
    /*------
2722
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2723
9.40k
         errmsg("%s is not allowed with GROUP BY clause",
2724
9.40k
            LCS_asString(strength))));
2725
9.40k
  if (qry->havingQual != NULL)
2726
9.40k
    ereport(ERROR,
2727
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2728
    /*------
2729
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2730
9.40k
         errmsg("%s is not allowed with HAVING clause",
2731
9.40k
            LCS_asString(strength))));
2732
9.40k
  if (qry->hasAggs)
2733
9.40k
    ereport(ERROR,
2734
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2735
    /*------
2736
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2737
9.40k
         errmsg("%s is not allowed with aggregate functions",
2738
9.40k
            LCS_asString(strength))));
2739
9.40k
  if (qry->hasWindowFuncs)
2740
9.40k
    ereport(ERROR,
2741
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2742
    /*------
2743
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2744
9.40k
         errmsg("%s is not allowed with window functions",
2745
9.40k
            LCS_asString(strength))));
2746
9.40k
  if (qry->hasTargetSRFs)
2747
9.40k
    ereport(ERROR,
2748
9.40k
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2749
    /*------
2750
      translator: %s is a SQL row locking clause such as FOR UPDATE */
2751
9.40k
         errmsg("%s is not allowed with set-returning functions in the target list",
2752
9.40k
            LCS_asString(strength))));
2753
9.40k
}
2754
2755
/*
2756
 * Transform a FOR [KEY] UPDATE/SHARE clause
2757
 *
2758
 * This basically involves replacing names by integer relids.
2759
 *
2760
 * NB: if you need to change this, see also markQueryForLocking()
2761
 * in rewriteHandler.c, and isLockedRefname() in parse_relation.c.
2762
 */
2763
static void
2764
transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
2765
             bool pushedDown)
2766
4.64k
{
2767
4.64k
  List     *lockedRels = lc->lockedRels;
2768
4.64k
  ListCell   *l;
2769
4.64k
  ListCell   *rt;
2770
4.64k
  Index   i;
2771
4.64k
  LockingClause *allrels;
2772
2773
4.64k
  CheckSelectLocking(qry, lc->strength);
2774
2775
  /* make a clause we can pass down to subqueries to select all rels */
2776
4.64k
  allrels = makeNode(LockingClause);
2777
4.64k
  allrels->lockedRels = NIL; /* indicates all rels */
2778
4.64k
  allrels->strength = lc->strength;
2779
4.64k
  allrels->waitPolicy = lc->waitPolicy;
2780
2781
4.64k
  if (lockedRels == NIL)
2782
2.81k
  {
2783
    /*
2784
     * Lock all regular tables used in query and its subqueries.  We
2785
     * examine inFromCl to exclude auto-added RTEs, particularly NEW/OLD
2786
     * in rules.  This is a bit of an abuse of a mostly-obsolete flag, but
2787
     * it's convenient.  We can't rely on the namespace mechanism that has
2788
     * largely replaced inFromCl, since for example we need to lock
2789
     * base-relation RTEs even if they are masked by upper joins.
2790
     */
2791
2.81k
    i = 0;
2792
2.81k
    foreach(rt, qry->rtable)
2793
2.82k
    {
2794
2.82k
      RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2795
2796
2.82k
      ++i;
2797
2.82k
      if (!rte->inFromCl)
2798
2
        continue;
2799
2.82k
      switch (rte->rtekind)
2800
2.82k
      {
2801
2.81k
        case RTE_RELATION:
2802
2.81k
          applyLockingClause(qry, i, lc->strength, lc->waitPolicy,
2803
2.81k
                     pushedDown);
2804
2.81k
          rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
2805
2.81k
          break;
2806
0
        case RTE_SUBQUERY:
2807
0
          applyLockingClause(qry, i, lc->strength, lc->waitPolicy,
2808
0
                     pushedDown);
2809
2810
          /*
2811
           * FOR UPDATE/SHARE of subquery is propagated to all of
2812
           * subquery's rels, too.  We could do this later (based on
2813
           * the marking of the subquery RTE) but it is convenient
2814
           * to have local knowledge in each query level about which
2815
           * rels need to be opened with RowShareLock.
2816
           */
2817
0
          transformLockingClause(pstate, rte->subquery,
2818
0
                       allrels, true);
2819
0
          break;
2820
4
        default:
2821
          /* ignore JOIN, SPECIAL, FUNCTION, VALUES, CTE RTEs */
2822
4
          break;
2823
2.82k
      }
2824
2.82k
    }
2825
2.81k
  }
2826
1.83k
  else
2827
1.83k
  {
2828
    /*
2829
     * Lock just the named tables.  As above, we allow locking any base
2830
     * relation regardless of alias-visibility rules, so we need to
2831
     * examine inFromCl to exclude OLD/NEW.
2832
     */
2833
1.83k
    foreach(l, lockedRels)
2834
1.82k
    {
2835
1.82k
      RangeVar   *thisrel = (RangeVar *) lfirst(l);
2836
2837
      /* For simplicity we insist on unqualified alias names here */
2838
1.82k
      if (thisrel->catalogname || thisrel->schemaname)
2839
1.82k
        ereport(ERROR,
2840
1.82k
            (errcode(ERRCODE_SYNTAX_ERROR),
2841
        /*------
2842
          translator: %s is a SQL row locking clause such as FOR UPDATE */
2843
1.82k
             errmsg("%s must specify unqualified relation names",
2844
1.82k
                LCS_asString(lc->strength)),
2845
1.82k
             parser_errposition(pstate, thisrel->location)));
2846
2847
1.82k
      i = 0;
2848
1.82k
      foreach(rt, qry->rtable)
2849
1.89k
      {
2850
1.89k
        RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2851
2852
1.89k
        ++i;
2853
1.89k
        if (!rte->inFromCl)
2854
4
          continue;
2855
1.89k
        if (strcmp(rte->eref->aliasname, thisrel->relname) == 0)
2856
1.82k
        {
2857
1.82k
          switch (rte->rtekind)
2858
1.82k
          {
2859
1.82k
            case RTE_RELATION:
2860
1.82k
              applyLockingClause(qry, i, lc->strength,
2861
1.82k
                         lc->waitPolicy, pushedDown);
2862
1.82k
              rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
2863
1.82k
              break;
2864
2
            case RTE_SUBQUERY:
2865
2
              applyLockingClause(qry, i, lc->strength,
2866
2
                         lc->waitPolicy, pushedDown);
2867
              /* see comment above */
2868
2
              transformLockingClause(pstate, rte->subquery,
2869
2
                           allrels, true);
2870
2
              break;
2871
0
            case RTE_JOIN:
2872
0
              ereport(ERROR,
2873
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2874
              /*------
2875
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2876
0
                   errmsg("%s cannot be applied to a join",
2877
0
                      LCS_asString(lc->strength)),
2878
0
                   parser_errposition(pstate, thisrel->location)));
2879
0
              break;
2880
0
            case RTE_FUNCTION:
2881
0
              ereport(ERROR,
2882
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2883
              /*------
2884
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2885
0
                   errmsg("%s cannot be applied to a function",
2886
0
                      LCS_asString(lc->strength)),
2887
0
                   parser_errposition(pstate, thisrel->location)));
2888
0
              break;
2889
0
            case RTE_TABLEFUNC:
2890
0
              ereport(ERROR,
2891
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2892
              /*------
2893
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2894
0
                   errmsg("%s cannot be applied to a table function",
2895
0
                      LCS_asString(lc->strength)),
2896
0
                   parser_errposition(pstate, thisrel->location)));
2897
0
              break;
2898
0
            case RTE_VALUES:
2899
0
              ereport(ERROR,
2900
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2901
              /*------
2902
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2903
0
                   errmsg("%s cannot be applied to VALUES",
2904
0
                      LCS_asString(lc->strength)),
2905
0
                   parser_errposition(pstate, thisrel->location)));
2906
0
              break;
2907
0
            case RTE_CTE:
2908
0
              ereport(ERROR,
2909
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2910
              /*------
2911
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2912
0
                   errmsg("%s cannot be applied to a WITH query",
2913
0
                      LCS_asString(lc->strength)),
2914
0
                   parser_errposition(pstate, thisrel->location)));
2915
0
              break;
2916
0
            case RTE_NAMEDTUPLESTORE:
2917
0
              ereport(ERROR,
2918
0
                  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2919
              /*------
2920
                translator: %s is a SQL row locking clause such as FOR UPDATE */
2921
0
                   errmsg("%s cannot be applied to a named tuplestore",
2922
0
                      LCS_asString(lc->strength)),
2923
0
                   parser_errposition(pstate, thisrel->location)));
2924
0
              break;
2925
0
            default:
2926
0
              elog(ERROR, "unrecognized RTE type: %d",
2927
0
                 (int) rte->rtekind);
2928
0
              break;
2929
1.82k
          }
2930
1.82k
          break;   /* out of foreach loop */
2931
1.82k
        }
2932
1.89k
      }
2933
1.82k
      if (rt == NULL)
2934
1.82k
        ereport(ERROR,
2935
1.82k
            (errcode(ERRCODE_UNDEFINED_TABLE),
2936
        /*------
2937
          translator: %s is a SQL row locking clause such as FOR UPDATE */
2938
1.82k
             errmsg("relation \"%s\" in %s clause not found in FROM clause",
2939
1.82k
                thisrel->relname,
2940
1.82k
                LCS_asString(lc->strength)),
2941
1.82k
             parser_errposition(pstate, thisrel->location)));
2942
1.82k
    }
2943
1.83k
  }
2944
4.64k
}
2945
2946
/*
2947
 * Record locking info for a single rangetable item
2948
 */
2949
void
2950
applyLockingClause(Query *qry, Index rtindex,
2951
           LockClauseStrength strength, LockWaitPolicy waitPolicy,
2952
           bool pushedDown)
2953
4.64k
{
2954
4.64k
  RowMarkClause *rc;
2955
2956
4.64k
  Assert(strength != LCS_NONE); /* else caller error */
2957
2958
  /* If it's an explicit clause, make sure hasForUpdate gets set */
2959
4.64k
  if (!pushedDown)
2960
4.64k
    qry->hasForUpdate = true;
2961
2962
  /* Check for pre-existing entry for same rtindex */
2963
4.64k
  if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
2964
0
  {
2965
    /*
2966
     * If the same RTE is specified with more than one locking strength,
2967
     * use the strongest.  (Reasonable, since you can't take both a shared
2968
     * and exclusive lock at the same time; it'll end up being exclusive
2969
     * anyway.)
2970
     *
2971
     * Similarly, if the same RTE is specified with more than one lock
2972
     * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in
2973
     * turn wins over waiting for the lock (the default).  This is a bit
2974
     * more debatable but raising an error doesn't seem helpful. (Consider
2975
     * for instance SELECT FOR UPDATE NOWAIT from a view that internally
2976
     * contains a plain FOR UPDATE spec.)  Having NOWAIT win over SKIP
2977
     * LOCKED is reasonable since the former throws an error in case of
2978
     * coming across a locked tuple, which may be undesirable in some
2979
     * cases but it seems better than silently returning inconsistent
2980
     * results.
2981
     *
2982
     * And of course pushedDown becomes false if any clause is explicit.
2983
     */
2984
0
    rc->strength = Max(rc->strength, strength);
2985
0
    rc->waitPolicy = Max(rc->waitPolicy, waitPolicy);
2986
0
    rc->pushedDown &= pushedDown;
2987
0
    return;
2988
0
  }
2989
2990
  /* Make a new RowMarkClause */
2991
4.64k
  rc = makeNode(RowMarkClause);
2992
0
  rc->rti = rtindex;
2993
4.64k
  rc->strength = strength;
2994
4.64k
  rc->waitPolicy = waitPolicy;
2995
4.64k
  rc->pushedDown = pushedDown;
2996
4.64k
  qry->rowMarks = lappend(qry->rowMarks, rc);
2997
4.64k
}
2998
2999
/*
3000
 * Coverage testing for raw_expression_tree_walker().
3001
 *
3002
 * When enabled, we run raw_expression_tree_walker() over every DML statement
3003
 * submitted to parse analysis.  Without this provision, that function is only
3004
 * applied in limited cases involving CTEs, and we don't really want to have
3005
 * to test everything inside as well as outside a CTE.
3006
 */
3007
#ifdef RAW_EXPRESSION_COVERAGE_TEST
3008
3009
static bool
3010
test_raw_expression_coverage(Node *node, void *context)
3011
{
3012
  if (node == NULL)
3013
    return false;
3014
  return raw_expression_tree_walker(node,
3015
                    test_raw_expression_coverage,
3016
                    context);
3017
}
3018
3019
#endif              /* RAW_EXPRESSION_COVERAGE_TEST */