summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/sql_values.cpp
diff options
context:
space:
mode:
authorvvvv <[email protected]>2024-11-07 12:29:36 +0300
committervvvv <[email protected]>2024-11-07 13:49:47 +0300
commitd4c258e9431675bab6745c8638df6e3dfd4dca6b (patch)
treeb5efcfa11351152a4c872fccaea35749141c0b11 /yql/essentials/sql/v1/sql_values.cpp
parent13a4f274caef5cfdaf0263b24e4d6bdd5521472b (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.cpp151
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