Skip to content

Commit 7df8dd2

Browse files
committed
Support temp tables in yql (ydb-platform#1589)
* Initial commit * Fixes
1 parent 321f683 commit 7df8dd2

File tree

7 files changed

+179
-3
lines changed

7 files changed

+179
-3
lines changed

ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,137 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
718718
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
719719
}
720720

721+
Y_UNIT_TEST(CreateTempTable) {
722+
NKikimrConfig::TAppConfig appConfig;
723+
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
724+
auto setting = NKikimrKqp::TKqpSetting();
725+
auto serverSettings = TKikimrSettings()
726+
.SetAppConfig(appConfig)
727+
.SetKqpSettings({setting});
728+
TKikimrRunner kikimr(
729+
serverSettings.SetWithSampleTables(false).SetEnableTempTables(true));
730+
auto clientConfig = NGRpcProxy::TGRpcClientConfig(kikimr.GetEndpoint());
731+
auto client = kikimr.GetQueryClient();
732+
{
733+
auto session = client.GetSession().GetValueSync().GetSession();
734+
auto id = session.GetId();
735+
736+
const auto queryCreate = Q_(R"(
737+
--!syntax_v1
738+
CREATE TEMP TABLE Temp (
739+
Key Uint64 NOT NULL,
740+
Value String,
741+
PRIMARY KEY (Key)
742+
);)");
743+
744+
auto resultCreate = session.ExecuteQuery(queryCreate, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
745+
UNIT_ASSERT_C(resultCreate.IsSuccess(), resultCreate.GetIssues().ToString());
746+
747+
const auto querySelect = Q_(R"(
748+
--!syntax_v1
749+
SELECT * FROM Temp;
750+
)");
751+
752+
auto resultSelect = session.ExecuteQuery(
753+
querySelect, NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
754+
UNIT_ASSERT_C(resultSelect.IsSuccess(), resultSelect.GetIssues().ToString());
755+
756+
bool allDoneOk = true;
757+
NTestHelpers::CheckDelete(clientConfig, id, Ydb::StatusIds::SUCCESS, allDoneOk);
758+
759+
UNIT_ASSERT(allDoneOk);
760+
}
761+
762+
{
763+
const auto querySelect = Q_(R"(
764+
--!syntax_v1
765+
SELECT * FROM Temp;
766+
)");
767+
768+
auto resultSelect = client.ExecuteQuery(
769+
querySelect, NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
770+
UNIT_ASSERT(!resultSelect.IsSuccess());
771+
}
772+
}
773+
774+
Y_UNIT_TEST(TempTablesDrop) {
775+
NKikimrConfig::TAppConfig appConfig;
776+
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
777+
auto setting = NKikimrKqp::TKqpSetting();
778+
auto serverSettings = TKikimrSettings()
779+
.SetAppConfig(appConfig)
780+
.SetKqpSettings({setting});
781+
TKikimrRunner kikimr(
782+
serverSettings.SetWithSampleTables(false).SetEnableTempTables(true));
783+
auto clientConfig = NGRpcProxy::TGRpcClientConfig(kikimr.GetEndpoint());
784+
auto client = kikimr.GetQueryClient();
785+
786+
auto session = client.GetSession().GetValueSync().GetSession();
787+
auto id = session.GetId();
788+
789+
const auto queryCreate = Q_(R"(
790+
--!syntax_v1
791+
CREATE TEMPORARY TABLE Temp (
792+
Key Uint64 NOT NULL,
793+
Value String,
794+
PRIMARY KEY (Key)
795+
);)");
796+
797+
auto resultCreate = session.ExecuteQuery(queryCreate, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
798+
UNIT_ASSERT_C(resultCreate.IsSuccess(), resultCreate.GetIssues().ToString());
799+
800+
{
801+
const auto querySelect = Q_(R"(
802+
--!syntax_v1
803+
SELECT * FROM Temp;
804+
)");
805+
806+
auto resultSelect = session.ExecuteQuery(
807+
querySelect, NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
808+
UNIT_ASSERT_C(resultSelect.IsSuccess(), resultSelect.GetIssues().ToString());
809+
}
810+
811+
const auto queryDrop = Q_(R"(
812+
--!syntax_v1
813+
DROP TABLE Temp;
814+
)");
815+
816+
auto resultDrop = session.ExecuteQuery(
817+
queryDrop, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
818+
UNIT_ASSERT_C(resultDrop.IsSuccess(), resultDrop.GetIssues().ToString());
819+
820+
{
821+
const auto querySelect = Q_(R"(
822+
--!syntax_v1
823+
SELECT * FROM Temp;
824+
)");
825+
826+
auto resultSelect = session.ExecuteQuery(
827+
querySelect, NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
828+
UNIT_ASSERT(!resultSelect.IsSuccess());
829+
}
830+
831+
bool allDoneOk = true;
832+
NTestHelpers::CheckDelete(clientConfig, id, Ydb::StatusIds::SUCCESS, allDoneOk);
833+
834+
UNIT_ASSERT(allDoneOk);
835+
836+
auto sessionAnother = client.GetSession().GetValueSync().GetSession();
837+
auto idAnother = sessionAnother.GetId();
838+
UNIT_ASSERT(id != idAnother);
839+
840+
{
841+
const auto querySelect = Q_(R"(
842+
--!syntax_v1
843+
SELECT * FROM Temp;
844+
)");
845+
846+
auto resultSelect = sessionAnother.ExecuteQuery(
847+
querySelect, NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
848+
UNIT_ASSERT(!resultSelect.IsSuccess());
849+
}
850+
}
851+
721852
Y_UNIT_TEST(DdlGroup) {
722853
NKikimrConfig::TAppConfig appConfig;
723854
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);

ydb/library/yql/sql/v1/SQLv1.g.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ object_features: object_feature | LPAREN object_feature (COMMA object_feature)*
623623

624624
object_type_ref: an_id_or_type;
625625

626-
create_table_stmt: CREATE (OR REPLACE)? (TABLE | TABLESTORE | EXTERNAL TABLE) (IF NOT EXISTS)? simple_table_ref LPAREN create_table_entry (COMMA create_table_entry)* COMMA? RPAREN
626+
create_table_stmt: CREATE (OR REPLACE)? (TABLE | TABLESTORE | EXTERNAL TABLE | TEMP TABLE | TEMPORARY TABLE) (IF NOT EXISTS)? simple_table_ref LPAREN create_table_entry (COMMA create_table_entry)* COMMA? RPAREN
627627
table_inherits?
628628
table_partition_by?
629629
with_table_settings?

ydb/library/yql/sql/v1/format/sql_format_ut.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,9 @@ Y_UNIT_TEST_SUITE(CheckSqlFormatter) {
307307
")\n"
308308
"PARTITION BY HASH (a, b, hash)\n"
309309
"WITH (tiering = 'some');\n"},
310-
{"create table if not exists user(user int32)", "CREATE TABLE IF NOT EXISTS user (\n\tuser int32\n);\n"}
310+
{"create table if not exists user(user int32)", "CREATE TABLE IF NOT EXISTS user (\n\tuser int32\n);\n"},
311+
{"create temp table user(user int32)", "CREATE TEMP TABLE user (\n\tuser int32\n);\n"},
312+
{"create temporary table user(user int32)", "CREATE TEMPORARY TABLE user (\n\tuser int32\n);\n"}
311313
};
312314

313315
TSetup setup;

ydb/library/yql/sql/v1/node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,7 @@ namespace NSQLTranslationV1 {
10461046
TVector<TChangefeedDescription> Changefeeds;
10471047
TTableSettings TableSettings;
10481048
ETableType TableType = ETableType::Table;
1049+
bool Temporary = false;
10491050
};
10501051

10511052
struct TAlterTableParameters {

ydb/library/yql/sql/v1/query.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,10 @@ class TCreateTableNode final: public TAstListNode {
11401140
break;
11411141
}
11421142

1143+
if (Params.Temporary) {
1144+
opts = L(opts, Q(Y(Q("temporary"))));
1145+
}
1146+
11431147
Add("block", Q(Y(
11441148
Y("let", "sink", Y("DataSink", BuildQuotedAtom(Pos, Table.Service), Scoped->WrapCluster(Table.Cluster, ctx))),
11451149
Y("let", "world", Y(TString(WriteName), "world", "sink", keys, Y("Void"), Q(opts))),

ydb/library/yql/sql/v1/sql_query.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,14 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core&
166166

167167
const auto& block = rule.GetBlock3();
168168
ETableType tableType = ETableType::Table;
169+
bool temporary = false;
169170
if (block.HasAlt2() && block.GetAlt2().GetToken1().GetId() == SQLv1LexerTokens::TOKEN_TABLESTORE) {
170171
tableType = ETableType::TableStore;
171172
} else if (block.HasAlt3() && block.GetAlt3().GetToken1().GetId() == SQLv1LexerTokens::TOKEN_EXTERNAL) {
172173
tableType = ETableType::ExternalTable;
174+
} else if (block.HasAlt4() && block.GetAlt4().GetToken1().GetId() == SQLv1LexerTokens::TOKEN_TEMP ||
175+
block.HasAlt5() && block.GetAlt5().GetToken1().GetId() == SQLv1LexerTokens::TOKEN_TEMPORARY) {
176+
temporary = true;
173177
}
174178

175179
bool existingOk = false;
@@ -193,7 +197,7 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core&
193197
return false;
194198
}
195199

196-
TCreateTableParameters params{.TableType=tableType};
200+
TCreateTableParameters params{.TableType=tableType, .Temporary=temporary};
197201
if (!CreateTableEntry(rule.GetRule_create_table_entry7(), params)) {
198202
return false;
199203
}

ydb/library/yql/sql/v1/sql_ut.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,40 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
10071007
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write!"]);
10081008
}
10091009

1010+
Y_UNIT_TEST(CreateTempTable) {
1011+
NYql::TAstParseResult res = SqlToYql("USE plato; CREATE TEMP TABLE t (a int32, primary key(a));");
1012+
UNIT_ASSERT(res.Root);
1013+
1014+
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
1015+
if (word == "Write!") {
1016+
UNIT_ASSERT_VALUES_UNEQUAL_C(TString::npos,
1017+
line.find(R"__((Write! world sink (Key '('tablescheme (String '"t"))) (Void) '('('mode 'create) '('columns '('('"a" (AsOptionalType (DataType 'Int32)) '('columnConstrains '()) '()))) '('primarykey '('"a")) '('temporary))))__"), line);
1018+
}
1019+
};
1020+
1021+
TWordCountHive elementStat = {{TString("Write!"), 0}};
1022+
VerifyProgram(res, elementStat, verifyLine);
1023+
1024+
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write!"]);
1025+
}
1026+
1027+
Y_UNIT_TEST(CreateTemporaryTable) {
1028+
NYql::TAstParseResult res = SqlToYql("USE plato; CREATE TEMPORARY TABLE t (a int32, primary key(a));");
1029+
UNIT_ASSERT(res.Root);
1030+
1031+
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
1032+
if (word == "Write!") {
1033+
UNIT_ASSERT_VALUES_UNEQUAL_C(TString::npos,
1034+
line.find(R"__((Write! world sink (Key '('tablescheme (String '"t"))) (Void) '('('mode 'create) '('columns '('('"a" (AsOptionalType (DataType 'Int32)) '('columnConstrains '()) '()))) '('primarykey '('"a")) '('temporary))))__"), line);
1035+
}
1036+
};
1037+
1038+
TWordCountHive elementStat = {{TString("Write!"), 0}};
1039+
VerifyProgram(res, elementStat, verifyLine);
1040+
1041+
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write!"]);
1042+
}
1043+
10101044
Y_UNIT_TEST(CreateTableDuplicatedPkColumnsFail) {
10111045
NYql::TAstParseResult res = SqlToYql("USE plato; CREATE TABLE t (a int32 not null, primary key(a, a));");
10121046
UNIT_ASSERT(!res.Root);

0 commit comments

Comments
 (0)