From 88e9e79aa133860fe216c6b0f4eaa1570b35668a Mon Sep 17 00:00:00 2001 From: dl239 Date: Tue, 17 Oct 2023 10:32:24 +0800 Subject: [PATCH] feat: support show create table (#3500) --- cases/plan/cmd.yaml | 17 +++ .../sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md | 28 ++++ docs/en/reference/sql/ddl/index.rst | 1 + .../ddl/SHOW_CREATE_TABLE_STATEMENT.md | 28 ++++ docs/zh/openmldb_sql/ddl/index.rst | 1 + hybridse/include/node/node_enum.h | 1 + hybridse/src/node/sql_node.cc | 1 + hybridse/src/planv2/ast_node_converter.cc | 1 + src/sdk/CMakeLists.txt | 3 + src/sdk/sdk_util.cc | 96 +++++++++++++ src/sdk/sdk_util.h | 35 +++++ src/sdk/sdk_util_test.cc | 127 ++++++++++++++++++ src/sdk/sql_cluster_router.cc | 39 ++++-- src/sdk/sql_cluster_test.cc | 18 +++ third-party/cmake/FetchZetasql.cmake | 8 +- 15 files changed, 392 insertions(+), 12 deletions(-) create mode 100644 docs/en/reference/sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md create mode 100644 docs/zh/openmldb_sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md create mode 100644 src/sdk/sdk_util.cc create mode 100644 src/sdk/sdk_util.h create mode 100644 src/sdk/sdk_util_test.cc diff --git a/cases/plan/cmd.yaml b/cases/plan/cmd.yaml index 3ca7d89ba6f..50b5fa94343 100644 --- a/cases/plan/cmd.yaml +++ b/cases/plan/cmd.yaml @@ -704,3 +704,20 @@ cases: +-actions: +-0: DropPathAction (12) +-1: AddPathAction (13) + + - id: show-create-table + desc: SHOW CREATE TABLE + sql: SHOW CREATE TABLE t1; + expect: + node_tree_str: | + +-node[CMD] + +-cmd_type: show create table + +-args: [t1] + - id: show-create-table-db + desc: SHOW CREATE TABLE + sql: SHOW CREATE TABLE db1.t1; + expect: + node_tree_str: | + +-node[CMD] + +-cmd_type: show create table + +-args: [db1, t1] diff --git a/docs/en/reference/sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md b/docs/en/reference/sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md new file mode 100644 index 00000000000..dd411410e65 --- /dev/null +++ b/docs/en/reference/sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md @@ -0,0 +1,28 @@ +# SHOW CREATE TABLE + +`SHOW CREATE TABLE` shows the `CREATE TABLE` statement that creates the named table + +**Syntax** + +```sql +SHOW CREATE TABLE table_name; +``` + +**Example** + +```sql +show create table t1; + ------- --------------------------------------------------------------- + Table Create Table + ------- --------------------------------------------------------------- + t1 CREATE TABLE `t1` ( + `c1` varchar, + `c2` int, + `c3` bigInt, + `c4` timestamp, + INDEX (KEY=`c1`, TS=`c4`, TTL_TYPE=ABSOLUTE, TTL=0m) + ) OPTIONS (PARTITIONNUM=8, REPLICANUM=2, STORAGE_MODE='HDD'); + ------- --------------------------------------------------------------- + +1 rows in set +``` \ No newline at end of file diff --git a/docs/en/reference/sql/ddl/index.rst b/docs/en/reference/sql/ddl/index.rst index 09199ec27ba..dbc94cc1f3d 100644 --- a/docs/en/reference/sql/ddl/index.rst +++ b/docs/en/reference/sql/ddl/index.rst @@ -23,3 +23,4 @@ Data Definition Statement (DDL) CREATE_FUNCTION SHOW_FUNCTIONS DROP_FUNCTION + SHOW_CREATE_TABLE_STATEMENT diff --git a/docs/zh/openmldb_sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md b/docs/zh/openmldb_sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md new file mode 100644 index 00000000000..e697f687846 --- /dev/null +++ b/docs/zh/openmldb_sql/ddl/SHOW_CREATE_TABLE_STATEMENT.md @@ -0,0 +1,28 @@ +# SHOW CREATE TABLE + +`SHOW CREATE TABLE` 用来显示指定表的建表语句 + +**Syntax** + +```sql +SHOW CREATE TABLE table_name; +``` + +**Example** + +```sql +show create table t1; + ------- --------------------------------------------------------------- + Table Create Table + ------- --------------------------------------------------------------- + t1 CREATE TABLE `t1` ( + `c1` varchar, + `c2` int, + `c3` bigInt, + `c4` timestamp, + INDEX (KEY=`c1`, TS=`c4`, TTL_TYPE=ABSOLUTE, TTL=0m) + ) OPTIONS (PARTITIONNUM=8, REPLICANUM=2, STORAGE_MODE='HDD'); + ------- --------------------------------------------------------------- + +1 rows in set +``` \ No newline at end of file diff --git a/docs/zh/openmldb_sql/ddl/index.rst b/docs/zh/openmldb_sql/ddl/index.rst index 116b9ce29c3..efd36734261 100644 --- a/docs/zh/openmldb_sql/ddl/index.rst +++ b/docs/zh/openmldb_sql/ddl/index.rst @@ -23,3 +23,4 @@ CREATE_FUNCTION SHOW_FUNCTIONS DROP_FUNCTION + SHOW_CREATE_TABLE_STATEMENT diff --git a/hybridse/include/node/node_enum.h b/hybridse/include/node/node_enum.h index 4fc914799d0..16e18291478 100644 --- a/hybridse/include/node/node_enum.h +++ b/hybridse/include/node/node_enum.h @@ -283,6 +283,7 @@ enum CmdType { kCmdShowFunctions, kCmdDropFunction, kCmdShowJobLog, + kCmdShowCreateTable, kCmdFake, // not a real cmd, for testing purpose only kLastCmd = kCmdFake, }; diff --git a/hybridse/src/node/sql_node.cc b/hybridse/src/node/sql_node.cc index bc5aec55cf9..16b88cd51ba 100644 --- a/hybridse/src/node/sql_node.cc +++ b/hybridse/src/node/sql_node.cc @@ -58,6 +58,7 @@ static absl::flat_hash_map CreateCmdTypeNamesMap() { {CmdType::kCmdDropTable, "drop table"}, {CmdType::kCmdShowProcedures, "show procedures"}, {CmdType::kCmdShowCreateSp, "show create procedure"}, + {CmdType::kCmdShowCreateTable, "show create table"}, {CmdType::kCmdDropSp, "drop procedure"}, {CmdType::kCmdDropIndex, "drop index"}, {CmdType::kCmdExit, "exit"}, diff --git a/hybridse/src/planv2/ast_node_converter.cc b/hybridse/src/planv2/ast_node_converter.cc index 19bb0ccfc6c..c0c3864716b 100644 --- a/hybridse/src/planv2/ast_node_converter.cc +++ b/hybridse/src/planv2/ast_node_converter.cc @@ -2172,6 +2172,7 @@ static const absl::flat_hash_map showTargetMap {"SESSION VARIABLES", {node::CmdType::kCmdShowSessionVariables}}, {"GLOBAL VARIABLES", {node::CmdType::kCmdShowGlobalVariables}}, {"CREATE PROCEDURE", {node::CmdType::kCmdShowCreateSp, true}}, + {"CREATE TABLE", {node::CmdType::kCmdShowCreateTable, true}}, {"DEPLOYMENT", {node::CmdType::kCmdShowDeployment, true}}, {"JOB", {node::CmdType::kCmdShowJob, true}}, {"COMPONENTS", {node::CmdType::kCmdShowComponents}}, diff --git a/src/sdk/CMakeLists.txt b/src/sdk/CMakeLists.txt index cc959f6a23b..28c41e09c52 100644 --- a/src/sdk/CMakeLists.txt +++ b/src/sdk/CMakeLists.txt @@ -26,6 +26,9 @@ if(TESTING_ENABLE) add_executable(db_sdk_test db_sdk_test.cc) target_link_libraries(db_sdk_test ${SDK_TEST_DEPS} ${BIN_LIBS} ${THIRD_LIBS}) + add_executable(sdk_util_test sdk_util_test.cc) + target_link_libraries(sdk_util_test ${SDK_TEST_DEPS} ${BIN_LIBS} ${THIRD_LIBS}) + add_executable(result_set_sql_test result_set_sql_test.cc) target_link_libraries(result_set_sql_test ${SDK_TEST_DEPS} ${BIN_LIBS} ${THIRD_LIBS}) diff --git a/src/sdk/sdk_util.cc b/src/sdk/sdk_util.cc new file mode 100644 index 00000000000..f6027f7c08b --- /dev/null +++ b/src/sdk/sdk_util.cc @@ -0,0 +1,96 @@ +/* + * Copyright 2021 4Paradigm + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sdk/sdk_util.h" + +#include +#include "codec/schema_codec.h" + +namespace openmldb { +namespace sdk { + +std::string SDKUtil::GenCreateTableSQL(const ::openmldb::nameserver::TableInfo& table_info) { + std::stringstream ss; + ss << "CREATE TABLE `" << table_info.name() << "` (\n"; + for (const auto& column : table_info.column_desc()) { + auto it = openmldb::codec::DATA_TYPE_STR_MAP.find(column.data_type()); + if (it != openmldb::codec::DATA_TYPE_STR_MAP.end()) { + ss << "`" << column.name() << "` " << it->second; + if (column.has_default_value()) { + ss << " DEFAULT '" << column.default_value() << "'"; + } + if (column.not_null()) { + ss << " NOT NULL"; + } + ss << ",\n"; + } + } + int index_cnt = 0; + for (const auto& index : table_info.column_key()) { + if (index.flag() != 0) { + continue; + } + if (index_cnt > 0) { + ss << ",\n"; + } + ss << "INDEX ("; + if (index.col_name_size() == 1) { + ss << "KEY=`" << index.col_name(0) << "`"; + } else { + ss << "KEY=("; + for (int idx = 0; idx < index.col_name_size(); idx++) { + if (idx > 0) { + ss << ","; + } + ss << "`" << index.col_name(idx) << "`"; + } + ss << ")"; + } + if (index.has_ts_name() && !index.ts_name().empty()) { + ss << ", TS=`" << index.ts_name() << "`"; + } + if (index.has_ttl()) { + ss << ", TTL_TYPE="; + if (index.ttl().ttl_type() == openmldb::type::TTLType::kAbsoluteTime) { + ss << "ABSOLUTE, TTL=" << index.ttl().abs_ttl() << "m"; + } else if (index.ttl().ttl_type() == openmldb::type::TTLType::kLatestTime) { + ss << "LATEST, TTL=" << index.ttl().lat_ttl(); + } else if (index.ttl().ttl_type() == openmldb::type::TTLType::kAbsAndLat) { + ss << "ABSANDLAT, TTL=(" << index.ttl().abs_ttl() << "m, " << index.ttl().lat_ttl() << ")"; + } else if (index.ttl().ttl_type() == openmldb::type::TTLType::kAbsOrLat) { + ss << "ABSORLAT, TTL=(" << index.ttl().abs_ttl() << "m, " << index.ttl().lat_ttl() << ")"; + } + } + index_cnt++; + ss << ")"; + } + ss << "\n) "; + ss << "OPTIONS ("; + ss << "PARTITIONNUM=" << table_info.partition_num(); + ss << ", REPLICANUM=" << table_info.replica_num(); + if (table_info.storage_mode() == openmldb::common::StorageMode::kSSD) { + ss << ", STORAGE_MODE='SSD'"; + } else if (table_info.storage_mode() == openmldb::common::StorageMode::kHDD) { + ss << ", STORAGE_MODE='HDD'"; + } else { + ss << ", STORAGE_MODE='Memory'"; + } + ss << ");"; + return ss.str(); +} + +} // namespace sdk +} // namespace openmldb diff --git a/src/sdk/sdk_util.h b/src/sdk/sdk_util.h new file mode 100644 index 00000000000..c3c6df9e407 --- /dev/null +++ b/src/sdk/sdk_util.h @@ -0,0 +1,35 @@ +/* + * Copyright 2021 4Paradigm + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SRC_SDK_SDK_UTIL_H_ +#define SRC_SDK_SDK_UTIL_H_ + +#include + +#include "proto/name_server.pb.h" + +namespace openmldb { +namespace sdk { + +class SDKUtil { + public: + static std::string GenCreateTableSQL(const ::openmldb::nameserver::TableInfo& table_info); +}; + +} // namespace sdk +} // namespace openmldb + +#endif // SRC_SDK_SDK_UTIL_H_ diff --git a/src/sdk/sdk_util_test.cc b/src/sdk/sdk_util_test.cc new file mode 100644 index 00000000000..c214f592cba --- /dev/null +++ b/src/sdk/sdk_util_test.cc @@ -0,0 +1,127 @@ +/* + * Copyright 2021 4Paradigm + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "absl/strings/str_split.h" +#include "absl/strings/numbers.h" +#include "gtest/gtest.h" +#include "codec/schema_codec.h" +#include "sdk/sdk_util.h" + +namespace openmldb { +namespace sdk { + +class SDKUtilTest : public ::testing::Test { + public: + SDKUtilTest() {} + ~SDKUtilTest() {} +}; + +void SetColumnDesc(const std::vector>& col_vec, + ::openmldb::nameserver::TableInfo* table_info) { + table_info->clear_column_desc(); + for (const auto& col : col_vec) { + auto col_desc = table_info->add_column_desc(); + col_desc->set_name(col[0]); + col_desc->set_data_type(codec::DATA_TYPE_MAP.find(col[1])->second); + if (col.size() > 2 && col[2] == "no") { + col_desc->set_not_null(true); + } + if (col.size() > 3 && !col[3].empty()) { + col_desc->set_default_value(col[3]); + } + } +} + +void SetIndex(const std::vector>& index_vec, + ::openmldb::nameserver::TableInfo* table_info) { + table_info->clear_column_key(); + for (const auto& index_val : index_vec) { + auto index = table_info->add_column_key(); + index->set_index_name(index_val[0]); + std::vector list = absl::StrSplit(index_val[1], ","); + for (const auto& name : list) { + index->add_col_name(name); + } + if (!index_val[2].empty()) { + index->set_ts_name(index_val[2]); + } + auto ttl = index->mutable_ttl(); + int abs_ttl; + int lat_ttl; + ASSERT_TRUE(absl::SimpleAtoi(index_val[4], &abs_ttl)); + ASSERT_TRUE(absl::SimpleAtoi(index_val[5], &lat_ttl)); + if (index_val[3] == "absolute") { + ttl->set_ttl_type(openmldb::type::TTLType::kAbsoluteTime); + ttl->set_abs_ttl(abs_ttl); + } else if (index_val[3] == "latest") { + ttl->set_ttl_type(openmldb::type::TTLType::kLatestTime); + ttl->set_lat_ttl(lat_ttl); + } else if (index_val[3] == "absorlat") { + ttl->set_ttl_type(openmldb::type::TTLType::kAbsAndLat); + ttl->set_abs_ttl(abs_ttl); + ttl->set_lat_ttl(lat_ttl); + } else if (index_val[3] == "absandlat") { + ttl->set_ttl_type(openmldb::type::TTLType::kAbsOrLat); + ttl->set_abs_ttl(abs_ttl); + ttl->set_lat_ttl(lat_ttl); + } + } +} + +TEST_F(SDKUtilTest, GenCreateTableSQL) { + ::openmldb::nameserver::TableInfo table_info; + std::vector> col = { {"col1", "string"}, {"col2", "int"}, {"col3", "bigint", "no"}}; + std::vector> index = { {"index1", "col1", "", "absolute", "100", "0"}}; + SetColumnDesc(col, &table_info); + SetIndex(index, &table_info); + table_info.set_replica_num(1); + table_info.set_partition_num(1); + table_info.set_name("t1"); + std::string exp_ddl = "CREATE TABLE `t1` (\n" + "`col1` string,\n" + "`col2` int,\n" + "`col3` bigInt NOT NULL,\n" + "INDEX (KEY=`col1`, TTL_TYPE=ABSOLUTE, TTL=100m)\n" + ") OPTIONS (PARTITIONNUM=1, REPLICANUM=1, STORAGE_MODE='Memory');"; + ASSERT_EQ(SDKUtil::GenCreateTableSQL(table_info), exp_ddl); + std::vector> col1 = { {"col1", "string", "no", "aa"}, + {"col2", "int"}, {"col3", "timestamp"}}; + std::vector> index1 = { {"index1", "col1", "", "absolute", "100", "0"}, + {"index2", "col1,col2", "col3", "absorlat", "100", "10"}}; + SetColumnDesc(col1, &table_info); + SetIndex(index1, &table_info); + table_info.set_replica_num(3); + table_info.set_partition_num(8); + table_info.set_storage_mode(openmldb::common::StorageMode::kHDD); + exp_ddl = "CREATE TABLE `t1` (\n" + "`col1` string DEFAULT 'aa' NOT NULL,\n" + "`col2` int,\n" + "`col3` timestamp,\n" + "INDEX (KEY=`col1`, TTL_TYPE=ABSOLUTE, TTL=100m),\n" + "INDEX (KEY=(`col1`,`col2`), TS=`col3`, TTL_TYPE=ABSANDLAT, TTL=(100m, 10))\n" + ") OPTIONS (PARTITIONNUM=8, REPLICANUM=3, STORAGE_MODE='HDD');"; + ASSERT_EQ(SDKUtil::GenCreateTableSQL(table_info), exp_ddl); +} + +} // namespace sdk +} // namespace openmldb + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sdk/sql_cluster_router.cc b/src/sdk/sql_cluster_router.cc index eea62b508ff..90054f277aa 100644 --- a/src/sdk/sql_cluster_router.cc +++ b/src/sdk/sql_cluster_router.cc @@ -55,6 +55,7 @@ #include "sdk/job_table_helper.h" #include "sdk/node_adapter.h" #include "sdk/result_set_sql.h" +#include "sdk/sdk_util.h" #include "sdk/split.h" #include "udf/udf.h" #include "vm/catalog.h" @@ -1625,15 +1626,37 @@ std::shared_ptr SQLClusterRouter::HandleSQLCmd(const h return ResultSetSQL::MakeResultSet({"Tables"}, values, status); } + case hybridse::node::kCmdShowCreateTable: { + auto& args = cmd_node->GetArgs(); + std::string cur_db = db; + std::string table_name; + if (!ParseNamesFromArgs(db, args, &cur_db, &table_name).IsOK()) { + *status = {StatusCode::kCmdError, msg}; + return {}; + } + if (cur_db.empty()) { + *status = {::hybridse::common::StatusCode::kCmdError, "please enter database first"}; + return {}; + } + auto table = cluster_sdk_->GetTableInfo(cur_db, table_name); + if (table == nullptr) { + *status = {StatusCode::kCmdError, "table " + table_name + " does not exist"}; + return {}; + } + std::string sql = SDKUtil::GenCreateTableSQL(*table); + std::vector> values; + std::vector vec = {table_name, sql}; + values.push_back(std::move(vec)); + return ResultSetSQL::MakeResultSet({"Table", "Create Table"}, values, status); + } + case hybridse::node::kCmdDescTable: { std::string cur_db = db; std::string table_name; const auto& args = cmd_node->GetArgs(); - if (args.size() > 1) { - cur_db = args[0]; - table_name = args[1]; - } else { - table_name = args[0]; + if (!ParseNamesFromArgs(db, args, &cur_db, &table_name).IsOK()) { + *status = {StatusCode::kCmdError, msg}; + return {}; } if (cur_db.empty()) { *status = {::hybridse::common::StatusCode::kCmdError, "please enter database first"}; @@ -2990,17 +3013,17 @@ ::hybridse::sdk::Status SQLClusterRouter::SetVariable(hybridse::node::SetPlanNod ::hybridse::sdk::Status SQLClusterRouter::ParseNamesFromArgs(const std::string& db, const std::vector& args, std::string* db_name, - std::string* sp_name) { + std::string* name) { if (args.size() == 1) { // only sp name, no db_name if (db.empty()) { return {StatusCode::kCmdError, "Please enter database first"}; } *db_name = db; - *sp_name = args[0]; + *name = args[0]; } else if (args.size() == 2) { *db_name = args[0]; - *sp_name = args[1]; + *name = args[1]; } else { return {StatusCode::kCmdError, "Invalid args"}; } diff --git a/src/sdk/sql_cluster_test.cc b/src/sdk/sql_cluster_test.cc index 359ac431573..70b6f7a20f2 100644 --- a/src/sdk/sql_cluster_test.cc +++ b/src/sdk/sql_cluster_test.cc @@ -257,6 +257,24 @@ TEST_F(SQLClusterDDLTest, CreateTableWithDatabase) { ASSERT_TRUE(router->DropDB(db2, &status)); } +TEST_F(SQLClusterDDLTest, ShowCreateTable) { + ::hybridse::sdk::Status status; + ASSERT_TRUE(router->ExecuteDDL(db, "drop table if exists t1;", &status)); + std::string ddl = "CREATE TABLE `t1` (\n" + "`col1` varchar,\n" + "`col2` int,\n" + "`col3` bigInt NOT NULL,\n" + "INDEX (KEY=`col1`, TTL_TYPE=ABSOLUTE, TTL=100m)\n" + ") OPTIONS (PARTITIONNUM=1, REPLICANUM=1, STORAGE_MODE='Memory');"; + ASSERT_TRUE(router->ExecuteDDL(db, ddl, &status)) << "ddl: " << ddl; + ASSERT_TRUE(router->RefreshCatalog()); + auto rs = router->ExecuteSQL(db, "show create table t1;", &status); + ASSERT_TRUE(status.IsOK()) << status.msg; + ASSERT_TRUE(rs->Next()); + ASSERT_EQ(ddl, rs->GetStringUnsafe(1)); + ASSERT_TRUE(router->ExecuteDDL(db, "drop table t1;", &status)); +} + TEST_F(SQLClusterDDLTest, CreateTableWithDatabaseWrongDDL) { std::string name = "test" + GenRand(); ::hybridse::sdk::Status status; diff --git a/third-party/cmake/FetchZetasql.cmake b/third-party/cmake/FetchZetasql.cmake index 09d4f3d6761..b2b1d580593 100644 --- a/third-party/cmake/FetchZetasql.cmake +++ b/third-party/cmake/FetchZetasql.cmake @@ -13,10 +13,10 @@ # limitations under the License. set(ZETASQL_HOME https://github.com/4paradigm/zetasql) -set(ZETASQL_VERSION 0.3.0) -set(ZETASQL_HASH_DARWIN 1b7e9c68d7fee29abf734be57934440b6891d4e80e22d8a92832518914373bea) -set(ZETASQL_HASH_LINUX_UBUNTU 0efb4feb822440e91ccd8c04d3a102cac9730745550168266b3544224fc86a63) -set(ZETASQL_HASH_LINUX_CENTOS 098ecb71b8a3dd7d8c6887d3b2b9306f0a130434f135754fd9930ccb11d80fed) +set(ZETASQL_VERSION 0.3.1) +set(ZETASQL_HASH_DARWIN 48bfdfe5fa91d414b0bf8383f116bc2a1f558c12fa286e49ea5ceede366dfbcf) +set(ZETASQL_HASH_LINUX_UBUNTU 3847ed7a60aeda1192adf7d702076d2db2bd49258992e2af67515a57b8f6f6a6) +set(ZETASQL_HASH_LINUX_CENTOS e73e6259ab2df3ae7289a9ae78600b69a8fbb6e4890d07a1031ccb1e37fa4281) set(ZETASQL_TAG v${ZETASQL_VERSION}) function(init_zetasql_urls)