Compile a RETURNING clause.
| 10370 | |
| 10371 | // Compile a RETURNING clause. |
| 10372 | static ReturningClause* dsqlProcessReturning(DsqlCompilerScratch* dsqlScratch, dsql_rel* relation, |
| 10373 | ReturningClause* input, bool singleton) |
| 10374 | { |
| 10375 | if (!input) |
| 10376 | return nullptr; |
| 10377 | |
| 10378 | auto& pool = dsqlScratch->getPool(); |
| 10379 | |
| 10380 | auto inputFirst = input->first; |
| 10381 | |
| 10382 | if (inputFirst->items.isEmpty()) |
| 10383 | { |
| 10384 | // Process RETURNING * |
| 10385 | inputFirst = FB_NEW_POOL(pool) ValueListNode(pool, 0u); |
| 10386 | dsqlExplodeFields(relation, inputFirst->items, true); |
| 10387 | } |
| 10388 | else |
| 10389 | { |
| 10390 | // Process alias.* items. |
| 10391 | inputFirst = PASS1_expand_select_list(dsqlScratch, inputFirst, nullptr); |
| 10392 | } |
| 10393 | |
| 10394 | const auto node = FB_NEW_POOL(pool) ReturningClause(pool); |
| 10395 | |
| 10396 | node->first = Node::doDsqlPass(dsqlScratch, inputFirst, false); |
| 10397 | |
| 10398 | dsqlScratch->flags |= DsqlCompilerScratch::FLAG_RETURNING_INTO; |
| 10399 | node->second = dsqlPassArray(dsqlScratch, |
| 10400 | dsqlScratch->returningClause ? dsqlScratch->returningClause->second : input->second); |
| 10401 | dsqlScratch->flags &= ~DsqlCompilerScratch::FLAG_RETURNING_INTO; |
| 10402 | |
| 10403 | if (!dsqlScratch->isPsql() && input->second) |
| 10404 | { |
| 10405 | // RETURNING INTO is not allowed syntax for DSQL |
| 10406 | ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << |
| 10407 | // Token unknown |
| 10408 | Arg::Gds(isc_token_err) << |
| 10409 | Arg::Gds(isc_random) << Arg::Str("INTO")); |
| 10410 | } |
| 10411 | else if (dsqlScratch->isPsql() && !input->second) |
| 10412 | { |
| 10413 | // This trick because we don't copy lexer positions when copying lists. |
| 10414 | const ValueListNode* errSrc = input->first; |
| 10415 | // RETURNING without INTO is not allowed for PSQL |
| 10416 | ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << |
| 10417 | // Unexpected end of command |
| 10418 | Arg::Gds(isc_command_end_err2) << Arg::Num(errSrc->line) << |
| 10419 | Arg::Num(errSrc->column)); |
| 10420 | } |
| 10421 | |
| 10422 | const unsigned count = node->first->items.getCount(); |
| 10423 | fb_assert(count); |
| 10424 | |
| 10425 | if (input->second) |
| 10426 | { |
| 10427 | fb_assert(dsqlScratch->isPsql()); |
| 10428 | |
| 10429 | if (count != node->second->items.getCount()) |
no test coverage detected