diff --git a/programs/local/LocalServer.cpp b/programs/local/LocalServer.cpp index e8ba7a8ee65..8149b5a4245 100644 --- a/programs/local/LocalServer.cpp +++ b/programs/local/LocalServer.cpp @@ -268,6 +268,7 @@ void LocalServer::tryInitPath() fs::create_directories(fs::path(path) / "metadata_dropped/"); global_context->setPath(path); + DatabaseCatalog::instance().fixPath(path); global_context->setTemporaryStoragePath(path + "tmp/", 0); global_context->setFlagsPath(path + "flags"); diff --git a/src/Interpreters/DatabaseCatalog.cpp b/src/Interpreters/DatabaseCatalog.cpp index 6d3300787ae..53acad1e133 100644 --- a/src/Interpreters/DatabaseCatalog.cpp +++ b/src/Interpreters/DatabaseCatalog.cpp @@ -1046,6 +1046,12 @@ String DatabaseCatalog::getPathForMetadata(const StorageID & table_id) const escapeForFileName(table_id.getTableName()) + ".sql"; } +//chdb session query need to fix the path +void DatabaseCatalog::fixPath(const String & path) +{ + getContext()->setPath(path); +} + void DatabaseCatalog::enqueueDroppedTableCleanup(StorageID table_id, StoragePtr table, String dropped_metadata_path, bool ignore_delay) { assert(table_id.hasUUID()); diff --git a/src/Interpreters/DatabaseCatalog.h b/src/Interpreters/DatabaseCatalog.h index edf1036b438..34b5391fc1b 100644 --- a/src/Interpreters/DatabaseCatalog.h +++ b/src/Interpreters/DatabaseCatalog.h @@ -250,6 +250,7 @@ class DatabaseCatalog : boost::noncopyable, WithMutableContext String getPathForDroppedMetadata(const StorageID & table_id) const; String getPathForMetadata(const StorageID & table_id) const; + void fixPath(const String & path); void enqueueDroppedTableCleanup(StorageID table_id, StoragePtr table, String dropped_metadata_path, bool ignore_delay = false); void dequeueDroppedTableCleanup(StorageID table_id); diff --git a/tests/test_issue135.py b/tests/test_issue135.py new file mode 100644 index 00000000000..485a86b28ea --- /dev/null +++ b/tests/test_issue135.py @@ -0,0 +1,48 @@ +#!python3 + +import shutil +import unittest +from chdb import session as chs + + +test_dir = ".state_tmp_auxten_issue135" + + +class TestReplaceTable(unittest.TestCase): + def setUp(self) -> None: + shutil.rmtree(test_dir, ignore_errors=True) + return super().setUp() + + def tearDown(self) -> None: + shutil.rmtree(test_dir, ignore_errors=True) + return super().tearDown() + + def test_replace_table(self): + sess = chs.Session(test_dir) + sess.query("CREATE DATABASE IF NOT EXISTS a;", "Debug") + sess.query( + "CREATE OR REPLACE TABLE a.test (id UInt64, updated_at DateTime DEFAULT now(),updated_at_date Date DEFAULT toDate(updated_at)) " + "ENGINE = MergeTree ORDER BY id;" + ) + sess.query("INSERT INTO a.test (id) Values (1);") + ret = sess.query("SELECT * FROM a.test;", "CSV") + # something like 1,"2023-11-20 21:59:57","2023-11-20" + parts = str(ret).split(",") + self.assertEqual(len(parts), 3) + self.assertEqual(parts[0], "1") + # regex for datetime + self.assertRegex(parts[1], r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") + # regex for date + self.assertRegex(parts[2], r"\d{4}-\d{2}-\d{2}") + + # replace table + sess.query( + "CREATE OR REPLACE TABLE a.test (id UInt64, updated_at DateTime DEFAULT now(),updated_at_date Date DEFAULT toDate(updated_at)) " + "ENGINE = MergeTree ORDER BY id;" + ) + ret = sess.query("SELECT * FROM a.test;", "CSV") + self.assertEqual(str(ret), "") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_stateful.py b/tests/test_stateful.py index 1db64236384..9e4371afdc8 100644 --- a/tests/test_stateful.py +++ b/tests/test_stateful.py @@ -93,6 +93,26 @@ def test_tmp(self): ret = sess2.query("SELECT chdb_xxx()", "CSV") self.assertEqual(str(ret), "") + def test_two_sessions(self): + sess1 = session.Session() + sess2 = session.Session() + sess1.query("CREATE FUNCTION chdb_xxx AS () -> 'sess1'", "CSV") + sess2.query("CREATE FUNCTION chdb_xxx AS () -> 'sess2'", "CSV") + sess1.query("CREATE DATABASE IF NOT EXISTS db_xxx ENGINE = Atomic", "CSV") + sess2.query("CREATE DATABASE IF NOT EXISTS db_xxx ENGINE = Atomic", "CSV") + sess1.query("CREATE TABLE IF NOT EXISTS db_xxx.tbl1 (x UInt8) ENGINE = Log;") + sess2.query("CREATE TABLE IF NOT EXISTS db_xxx.tbl2 (x UInt8) ENGINE = Log;") + sess1.query("INSERT INTO db_xxx.tbl1 VALUES (1), (2), (3), (4);") + sess2.query("INSERT INTO db_xxx.tbl2 VALUES (5), (6), (7), (8);") + ret = sess1.query("SELECT chdb_xxx()", "CSV") + self.assertEqual(str(ret), '"sess1"\n') + ret = sess2.query("SELECT chdb_xxx()", "CSV") + self.assertEqual(str(ret), '"sess2"\n') + ret = sess1.query("SELECT * FROM db_xxx.tbl1", "CSV") + self.assertEqual(str(ret), "1\n2\n3\n4\n") + ret = sess2.query("SELECT * FROM db_xxx.tbl2", "CSV") + self.assertEqual(str(ret), "5\n6\n7\n8\n") + def test_context_mgr(self): with session.Session() as sess: sess.query("CREATE FUNCTION chdb_xxx AS () -> '0.12.0'", "CSV")