diff options
author | vvvv <[email protected]> | 2024-11-07 12:29:36 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2024-11-07 13:49:47 +0300 |
commit | d4c258e9431675bab6745c8638df6e3dfd4dca6b (patch) | |
tree | b5efcfa11351152a4c872fccaea35749141c0b11 /yql/essentials/sql/v1/sql_values.cpp | |
parent | 13a4f274caef5cfdaf0263b24e4d6bdd5521472b (diff) |
Moved other yql/essentials libs YQL-19206
init
commit_hash:7d4c435602078407bbf20dd3c32f9c90d2bbcbc0
Diffstat (limited to 'yql/essentials/sql/v1/sql_values.cpp')
-rw-r--r-- | yql/essentials/sql/v1/sql_values.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/yql/essentials/sql/v1/sql_values.cpp b/yql/essentials/sql/v1/sql_values.cpp new file mode 100644 index 00000000000..c035489387f --- /dev/null +++ b/yql/essentials/sql/v1/sql_values.cpp @@ -0,0 +1,151 @@ +#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 |