123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- #include "sql_values.h"
- #include "sql_group_by.h"
- #include "sql_query.h"
- #include "sql_select.h"
- #include "sql_expression.h"
- #include "source.h"
- namespace NSQLTranslationV1 {
- using namespace NSQLv1Generated;
- TSourcePtr TSqlValues::Build(const TRule_values_stmt& node, TPosition& valuesPos, const TVector<TString>& derivedColumns, TPosition derivedColumnsPos) {
- Token(node.GetToken1());
- valuesPos = Ctx.Pos();
- TVector<TVector<TNodePtr>> rows;
- const auto& rowList = node.GetRule_values_source_row_list2();
- if (!BuildRows(rowList, rows)) {
- return nullptr;
- }
- YQL_ENSURE(!rows.empty());
- const size_t columnsCount = rows.back().size();
- if (derivedColumns.size() > columnsCount) {
- Ctx.Error(derivedColumnsPos) << "Derived column list size exceeds column count in VALUES";
- return nullptr;
- }
- auto columns = derivedColumns;
- if (Ctx.WarnUnnamedColumns && columns.size() < columnsCount) {
- Ctx.Warning(valuesPos, TIssuesIds::YQL_UNNAMED_COLUMN)
- << "Autogenerated column names column" << columns.size() << "...column" << columnsCount - 1 << " will be used here";
- }
- while (columns.size() < columnsCount) {
- columns.push_back(TStringBuilder() << "column" << columns.size());
- }
- TVector<TNodePtr> labels;
- for (size_t i = 0; i < columnsCount; ++i) {
- labels.push_back(BuildQuotedAtom(derivedColumnsPos, columns[i]));
- }
- TVector<TNodePtr> items;
- for (auto& row : rows) {
- YQL_ENSURE(!row.empty());
- YQL_ENSURE(row.size() == columnsCount);
- items.push_back(BuildOrderedStructure(row.front()->GetPos(), row, labels));
- }
- auto list = new TCallNodeImpl(valuesPos, "AsListMayWarn", items);
- list = new TCallNodeImpl(valuesPos, "PersistableRepr", { list });
- list = new TCallNodeImpl(valuesPos, "AssumeColumnOrder", { list, BuildTuple(valuesPos, labels) });
- auto result = BuildNodeSource(valuesPos, list, false);
- result->AllColumns();
- return result;
- }
- bool TSqlValues::BuildRows(const TRule_values_source_row_list& node, TVector<TVector<TNodePtr>>& rows) {
- rows = TVector<TVector<TNodePtr>> {{}};
- if (!BuildRow(node.GetRule_values_source_row1(), rows.back())) {
- return false;
- }
- const size_t rowSize = rows.back().size();
- for (const auto& valuesSourceRow: node.GetBlock2()) {
- rows.push_back({});
- if (!BuildRow(valuesSourceRow.GetRule_values_source_row2(), rows.back())) {
- return false;
- }
- if (rows.back().size() != rowSize) {
- Token(valuesSourceRow.GetRule_values_source_row2().GetToken1());
- Error() << "All VALUES items should have same size: expecting " << rowSize << ", got " << rows.back().size();
- return false;
- }
- }
- return true;
- }
- bool TSqlValues::BuildRow(const TRule_values_source_row& inRow, TVector<TNodePtr>& outRow) {
- TSqlExpression sqlExpr(Ctx, Mode);
- return ExprList(sqlExpr, outRow, inRow.GetRule_expr_list2());
- }
- TSourcePtr TSqlValues::ValuesSource(const TRule_values_source& node, const TVector<TString>& columnsHint,
- const TString& operationName)
- {
- Ctx.IncrementMonCounter("sql_features", "ValuesSource");
- TPosition pos(Ctx.Pos());
- switch (node.Alt_case()) {
- case TRule_values_source::kAltValuesSource1: {
- TVector<TVector<TNodePtr>> rows {{}};
- const auto& rowList = node.GetAlt_values_source1().GetRule_values_stmt1().GetRule_values_source_row_list2();
- if (!BuildRows(rowList, rows)) {
- return nullptr;
- }
- return BuildWriteValues(pos, operationName, columnsHint, rows);
- }
- case TRule_values_source::kAltValuesSource2: {
- TSqlSelect select(Ctx, Mode);
- TPosition selectPos;
- auto source = select.Build(node.GetAlt_values_source2().GetRule_select_stmt1(), selectPos);
- if (!source) {
- return nullptr;
- }
- return BuildWriteValues(pos, "UPDATE", columnsHint, std::move(source));
- }
- default:
- Ctx.IncrementMonCounter("sql_errors", "UnknownValuesSource");
- AltNotImplemented("values_source", node);
- return nullptr;
- }
- }
- TSourcePtr TSqlIntoValues::Build(const TRule_into_values_source& node, const TString& operationName) {
- switch (node.Alt_case()) {
- case TRule_into_values_source::kAltIntoValuesSource1: {
- auto alt = node.GetAlt_into_values_source1();
- TVector<TString> columnsHint;
- if (alt.HasBlock1()) {
- PureColumnListStr(alt.GetBlock1().GetRule_pure_column_list1(), *this, columnsHint);
- }
- return ValuesSource(alt.GetRule_values_source2(), columnsHint, operationName);
- }
- default:
- Ctx.IncrementMonCounter("sql_errors", "DefaultValuesOrOther");
- AltNotImplemented("into_values_source", node);
- return nullptr;
- }
- }
- TSourcePtr TSqlAsValues::Build(const TRule_values_source& node, const TString& operationName) {
- switch (node.Alt_case()) {
- case TRule_values_source::kAltValuesSource1: {
- Ctx.IncrementMonCounter("sql_errors", "UnknownValuesSource");
- Error() << "AS VALUES statement is not supported for " << operationName << ".";
- return nullptr;
- }
- case TRule_values_source::kAltValuesSource2: {
- return ValuesSource(node, {}, operationName);
- }
- default:
- Ctx.IncrementMonCounter("sql_errors", "UnknownValuesSource");
- AltNotImplemented("values_source", node);
- return nullptr;
- }
- }
- } // namespace NSQLTranslationV1
|