diff --git a/ydb/library/yql/ast/yql_expr.h b/ydb/library/yql/ast/yql_expr.h index 21329b8ab0a2..3ce03fe1df25 100644 --- a/ydb/library/yql/ast/yql_expr.h +++ b/ydb/library/yql/ast/yql_expr.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -531,6 +532,26 @@ class TStructExprType : public TTypeAnnotationNode { return it - Items.begin(); } + TMaybe FindItemI(const TStringBuf& name) const { + auto strict = FindItem(name); + if (strict) { + return strict; + } + + TMaybe ret; + for (ui32 i = 0; i < Items.size(); ++i) { + if (AsciiEqualsIgnoreCase(name, Items[i]->GetName())) { + if (ret) { + return Nothing(); + } + + ret = i; + } + } + + return ret; + } + const TTypeAnnotationNode* FindItemType(const TStringBuf& name) const { const auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess()); if (it == Items.end() || (*it)->GetName() != name) { diff --git a/ydb/library/yql/core/type_ann/type_ann_pg.cpp b/ydb/library/yql/core/type_ann/type_ann_pg.cpp index c0960439516c..c28736d2928b 100644 --- a/ydb/library/yql/core/type_ann/type_ann_pg.cpp +++ b/ydb/library/yql/core/type_ann/type_ann_pg.cpp @@ -151,7 +151,7 @@ IGraphTransformer::TStatus InferPgCommonType(TPositionHandle pos, const TExprNod { size_t j = 0; for (const auto& col : *childColumnOrder) { - auto itemIdx = structType->FindItem(col); + auto itemIdx = structType->FindItemI(col); YQL_ENSURE(itemIdx); const auto* type = structType->GetItems()[*itemIdx]->GetItemType(); @@ -1577,7 +1577,7 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet& } } - auto pos = x.Type->FindItem(node->Tail().Content()); + auto pos = x.Type->FindItemI(node->Tail().Content()); if (pos) { foundAlias = x.Alias; ++matches; @@ -1589,7 +1589,7 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet& } if (x.Priority == TInput::External) { - x.UsedExternalColumns.insert(TString(node->Tail().Content())); + x.UsedExternalColumns.insert(TString(x.Type->GetItems()[*pos]->GetName())); } } } @@ -1780,12 +1780,12 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSetFindItem(ref); + auto pos = x.Type->FindItemI(ref); if (pos) { auto item = x.Type->GetItems()[*pos]; item = AddAlias(x.Alias, item, ctx); items.push_back(item); - usedRefs.insert(ref); + usedRefs.insert(TString(item->GetName())); } } @@ -1795,7 +1795,7 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSetfind(x.Alias)->second) { - auto pos = x.Type->FindItem(ref); + auto pos = x.Type->FindItemI(ref); if (pos) { auto item = x.Type->GetItems()[*pos]; item = AddAlias(x.Alias, item, ctx); @@ -1882,12 +1882,12 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con } } - auto pos = x.Type->FindItem(node->Tail().Content()); + auto pos = x.Type->FindItemI(node->Tail().Content()); if (pos) { return ctx.Expr.Builder(node->Pos()) .Callable("Member") .Add(0, argNode) - .Atom(1, MakeAliasedColumn(x.Alias, node->Tail().Content())) + .Atom(1, MakeAliasedColumn(x.Alias, x.Type->GetItems()[*pos]->GetName())) .Seal() .Build(); } @@ -2754,7 +2754,7 @@ bool GatherExtraSortColumns(const TExprNode& data, const TInputs& inputs, TExprN continue; } - auto pos = x.Type->FindItem(column); + auto pos = x.Type->FindItemI(column); if (pos) { index = inputIndex; break; @@ -3396,7 +3396,7 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN TVector newStructItems; TColumnOrder newOrder; for (ui32 i = 0; i < p->Child(2)->ChildrenSize(); ++i) { - auto pos = inputStructType->FindItem((*columnOrder)[i]); + auto pos = inputStructType->FindItemI((*columnOrder)[i]); YQL_ENSURE(pos); auto type = inputStructType->GetItems()[*pos]->GetItemType(); newOrder.push_back(TString(p->Child(2)->Child(i)->Content())); @@ -4147,7 +4147,7 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN const auto type = data.Child(j)->Tail().GetTypeAnn()->Cast()-> GetType()->Cast(); for (const auto& col : x.UsedExternalColumns) { - auto pos = type->FindItem(col); + auto pos = type->FindItemI(col); YQL_ENSURE(pos); items.push_back(type->GetItems()[*pos]); } diff --git a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp index 930a9ed9e76a..a853923ba5ce 100644 --- a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp +++ b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp @@ -411,12 +411,13 @@ class TPgTableContent : public TMutableComputationNode { ApplyFillers(AllPgDatabaseStatFillers, Y_ARRAY_SIZE(AllPgDatabaseStatFillers), PgDatabaseStatFillers_); } else if (Table_ == "pg_class") { static const std::pair AllPgClassFillers[] = { - {"oid", [](const NPg::TTableInfo& desc, ui32) { return ScalarDatumToPod(ObjectIdGetDatum(desc.Oid)); }}, - {"relispartition", [](const NPg::TTableInfo&, ui32) { return ScalarDatumToPod(BoolGetDatum(false)); }}, - {"relkind", [](const NPg::TTableInfo& desc, ui32) { return ScalarDatumToPod(CharGetDatum(desc.Kind)); }}, - {"relname", [](const NPg::TTableInfo& desc, ui32) { return PointerDatumToPod((Datum)MakeFixedString(desc.Name, NAMEDATALEN)); }}, - {"relnamespace", [](const NPg::TTableInfo&, ui32 namespaceOid) { return ScalarDatumToPod(ObjectIdGetDatum(namespaceOid)); }}, - {"relowner", [](const NPg::TTableInfo&, ui32) { return ScalarDatumToPod(ObjectIdGetDatum(1)); }}, + {"oid", [](const NPg::TTableInfo& desc, ui32, ui32) { return ScalarDatumToPod(ObjectIdGetDatum(desc.Oid)); }}, + {"relispartition", [](const NPg::TTableInfo&, ui32, ui32) { return ScalarDatumToPod(BoolGetDatum(false)); }}, + {"relkind", [](const NPg::TTableInfo& desc, ui32, ui32) { return ScalarDatumToPod(CharGetDatum(desc.Kind)); }}, + {"relname", [](const NPg::TTableInfo& desc, ui32, ui32) { return PointerDatumToPod((Datum)MakeFixedString(desc.Name, NAMEDATALEN)); }}, + {"relnamespace", [](const NPg::TTableInfo&, ui32 namespaceOid,ui32) { return ScalarDatumToPod(ObjectIdGetDatum(namespaceOid)); }}, + {"relowner", [](const NPg::TTableInfo&, ui32, ui32) { return ScalarDatumToPod(ObjectIdGetDatum(1)); }}, + {"relam", [](const NPg::TTableInfo&, ui32, ui32 amOid) { return ScalarDatumToPod(ObjectIdGetDatum(amOid)); }}, }; ApplyFillers(AllPgClassFillers, Y_ARRAY_SIZE(AllPgClassFillers), PgClassFillers_); @@ -650,11 +651,19 @@ class TPgTableContent : public TMutableComputationNode { namespaces[desc.Name] = oid; }); + ui32 btreeAmOid = 0; + NPg::EnumAm([&](ui32 oid, const NPg::TAmDesc& desc) { + if (desc.AmName == "btree") { + btreeAmOid = oid; + } + }); + for (const auto& t : tables) { NUdf::TUnboxedValue* items; auto row = compCtx.HolderFactory.CreateDirectArrayHolder(PgClassFillers_.size(), items); for (ui32 i = 0; i < PgClassFillers_.size(); ++i) { - items[i] = PgClassFillers_[i](t, namespaces[t.Schema]); + ui32 amOid = (t.Kind == NPg::ERelKind::Relation) ? btreeAmOid : 0; + items[i] = PgClassFillers_[i](t, namespaces[t.Schema], amOid); } rows.emplace_back(row); @@ -735,7 +744,7 @@ class TPgTableContent : public TMutableComputationNode { using TColumnsFiller = NUdf::TUnboxedValuePod(*)(const NPg::TColumnInfo&); TVector ColumnsFillers_; - using TPgClassFiller = NUdf::TUnboxedValuePod(*)(const NPg::TTableInfo&, ui32 namespaceOid); + using TPgClassFiller = NUdf::TUnboxedValuePod(*)(const NPg::TTableInfo&, ui32 namespaceOid, ui32 amOid); TVector PgClassFillers_; }; diff --git a/ydb/library/yql/sql/pg/pg_sql.cpp b/ydb/library/yql/sql/pg/pg_sql.cpp index 3caaced06702..1c05938c6652 100644 --- a/ydb/library/yql/sql/pg/pg_sql.cpp +++ b/ydb/library/yql/sql/pg/pg_sql.cpp @@ -142,6 +142,10 @@ int StrCompare(const char* s1, const char* s2) { return strcmp(s1 ? s1 : "", s2 ? s2 : ""); } +int StrICompare(const char* s1, const char* s2) { + return stricmp(s1 ? s1 : "", s2 ? s2 : ""); +} + std::shared_ptr ListMake1(void* cell) { return std::shared_ptr(list_make1(cell), list_free); } @@ -2104,7 +2108,7 @@ class TConverter : public IPGParseEvents { AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option"); return nullptr; } - TString rawStr = TString(StrVal(val)); + TString rawStr = to_lower(TString(StrVal(val))); if (name != "search_path") { AddError(TStringBuilder() << "VariableSetStmt, set_config doesn't support that option:" << name); return nullptr; @@ -2561,20 +2565,27 @@ class TConverter : public IPGParseEvents { TAstNode* BuildClusterSinkOrSourceExpression( bool isSink, const TStringBuf schemaname) { - const auto p = Settings.ClusterMapping.FindPtr(schemaname); + TString usedCluster(schemaname); + auto p = Settings.ClusterMapping.FindPtr(usedCluster); + if (!p) { + usedCluster = to_lower(usedCluster); + p = Settings.ClusterMapping.FindPtr(usedCluster); + } + if (!p) { AddError(TStringBuilder() << "Unknown cluster: " << schemaname); return nullptr; } - return L(isSink ? A("DataSink") : A("DataSource"), QAX(*p), QAX(schemaname.Data())); + return L(isSink ? A("DataSink") : A("DataSource"), QAX(*p), QAX(usedCluster)); } TAstNode* BuildTableKeyExpression(const TStringBuf relname, const TStringBuf cluster, bool isScheme = false ) { - bool noPrefix = (cluster == "pg_catalog" || cluster == "information_schema"); - TString tableName = noPrefix ? TString(relname) : TablePathPrefix + relname; + auto lowerCluster = to_lower(TString(cluster)); + bool noPrefix = (lowerCluster == "pg_catalog" || lowerCluster == "information_schema"); + TString tableName = noPrefix ? to_lower(TString(relname)) : TablePathPrefix + relname; return L(A("Key"), QL(QA(isScheme ? "tablescheme" : "table"), L(A("String"), QAX(std::move(tableName))))); } @@ -3520,7 +3531,7 @@ class TConverter : public IPGParseEvents { !typeName->pct_type && (ListLength(typeName->names) == 2 && NodeTag(ListNodeNth(typeName->names, 0)) == T_String && - !StrCompare(StrVal(ListNodeNth(typeName->names, 0)), "pg_catalog") || ListLength(typeName->names) == 1) && + !StrICompare(StrVal(ListNodeNth(typeName->names, 0)), "pg_catalog") || ListLength(typeName->names) == 1) && NodeTag(ListNodeNth(typeName->names, ListLength(typeName->names) - 1)) == T_String; if (NodeTag(arg) == T_A_Const && diff --git a/ydb/library/yql/tests/sql/dq_file/part12/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part12/canondata/result.json index fcb85e767b6a..546bb33a091d 100644 --- a/ydb/library/yql/tests/sql/dq_file/part12/canondata/result.json +++ b/ydb/library/yql/tests/sql/dq_file/part12/canondata/result.json @@ -2515,9 +2515,9 @@ ], "test.test[pg_catalog-pg_class-default.txt-Debug]": [ { - "checksum": "ec01c3e80fa9ed400a36e0e984f826bd", - "size": 7046, - "uri": "https://{canondata_backend}/1936997/15647165297f31fc500aaeb8506af785801000d5/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql_patched" + "checksum": "b798d692cdb0050db23e0af30a0bf365", + "size": 7854, + "uri": "https://{canondata_backend}/1936273/86cc69b84d2bd29ced3a8946b9d79484a91fffaa/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql_patched" } ], "test.test[pg_catalog-pg_class-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/hybrid_file/part8/canondata/result.json b/ydb/library/yql/tests/sql/hybrid_file/part8/canondata/result.json index e4328e3c83da..e7d043b17fbc 100644 --- a/ydb/library/yql/tests/sql/hybrid_file/part8/canondata/result.json +++ b/ydb/library/yql/tests/sql/hybrid_file/part8/canondata/result.json @@ -2381,9 +2381,9 @@ ], "test.test[pg_catalog-pg_class-default.txt-Debug]": [ { - "checksum": "fb682e3f79671dbce0b6f7bdea376718", - "size": 7045, - "uri": "https://{canondata_backend}/1781765/9c2a131db7c99a7c31942aabf8738f3bac969d91/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql_patched" + "checksum": "afa755b11b36a96a2cecf6f10b7ee834", + "size": 7853, + "uri": "https://{canondata_backend}/1880306/9b3d48683fc0ab2f3a465a16fcec6b6f0793c208/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql_patched" } ], "test.test[pg_catalog-pg_class-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json index 169b7c6bb9e0..fb46ba05758b 100644 --- a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json +++ b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json @@ -13322,9 +13322,9 @@ ], "test_sql2yql.test[pg_catalog-pg_class]": [ { - "checksum": "714f0205f14cecf109480cb2fc163a16", - "size": 1809, - "uri": "https://{canondata_backend}/1777230/0c388884f13a4e27fa979282c1cb1b2af98b6a1e/resource.tar.gz#test_sql2yql.test_pg_catalog-pg_class_/sql.yql" + "checksum": "1a29aea58de89c752df9fbb263f12260", + "size": 1983, + "uri": "https://{canondata_backend}/1942173/1a97c7aac68c22baf8625fe091ac9f4c169b3dd4/resource.tar.gz#test_sql2yql.test_pg_catalog-pg_class_/sql.yql" } ], "test_sql2yql.test[pg_catalog-pg_database]": [ diff --git a/ydb/library/yql/tests/sql/suites/pg_catalog/pg_class.sql b/ydb/library/yql/tests/sql/suites/pg_catalog/pg_class.sql index e3be64c5f4b2..28f3d66e2823 100644 --- a/ydb/library/yql/tests/sql/suites/pg_catalog/pg_class.sql +++ b/ydb/library/yql/tests/sql/suites/pg_catalog/pg_class.sql @@ -12,7 +12,9 @@ max(relispartition::text) max_isrel, max(relkind) max_relkind, max(relname) max_relname, max(relnamespace) max_relns, -max(relowner) max_relowner +max(relowner) max_relowner, +min(relam) min_am, +max(relam) max_am from pg_catalog.pg_class; diff --git a/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json index b9877b48d940..7dcb370e96ca 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json @@ -2348,9 +2348,9 @@ ], "test.test[pg_catalog-pg_class-default.txt-Debug]": [ { - "checksum": "cae74a693d7a4e3f1578f754adcae5c6", - "size": 6971, - "uri": "https://{canondata_backend}/1871182/f42651a4c8505a845b01023d9d7e8e03f2e50c2d/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql" + "checksum": "99f6276f6794cfca07f55964603dacfe", + "size": 7779, + "uri": "https://{canondata_backend}/1937492/1e7a7859528b242167c1536c8c76d6682b16c41b/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Debug_/opt.yql" } ], "test.test[pg_catalog-pg_class-default.txt-Plan]": [ @@ -2362,9 +2362,9 @@ ], "test.test[pg_catalog-pg_class-default.txt-Results]": [ { - "checksum": "878ba76e165d869792a16cc18e29da6e", - "size": 4209, - "uri": "https://{canondata_backend}/1871182/f42651a4c8505a845b01023d9d7e8e03f2e50c2d/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Results_/results.txt" + "checksum": "b706bba317a2352e9f76e66be6443028", + "size": 4787, + "uri": "https://{canondata_backend}/1937492/1e7a7859528b242167c1536c8c76d6682b16c41b/resource.tar.gz#test.test_pg_catalog-pg_class-default.txt-Results_/results.txt" } ], "test.test[pg_catalog-pg_description_pg_syntax-default.txt-Debug]": [