blob: 6f91323d63db999b758286d315eea236963c2530 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 <Columns/ColumnSet.h>
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/DataTypeSet.h>
#include <Functions/FunctionFactory.h>
#include <Interpreters/Set.h>
#include <gtest/gtest.h>
#include <Common/BlockTypeUtils.h>
#include <Common/DebugUtils.h>
#include <Common/QueryContext.h>
#include "IO/ReadBufferFromString.h"
TEST(TestFunction, murmurHash2_64)
{
using namespace DB;
auto & factory = FunctionFactory::instance();
auto function = factory.get("murmurHash2_64", local_engine::QueryContext::globalContext());
auto type0 = DataTypeFactory::instance().get("String");
auto column0 = type0->createColumn();
column0->insert("A");
column0->insert("A");
column0->insert("B");
column0->insert("c");
auto column1 = type0->createColumn();
column1->insert("X");
column1->insert("X");
column1->insert("Y");
column1->insert("Z");
ColumnsWithTypeAndName columns
= {ColumnWithTypeAndName(std::move(column0), type0, "string0"), ColumnWithTypeAndName(std::move(column1), type0, "string0")};
Block block(columns);
std::cerr << "input:\n";
debug::headBlock(block);
auto executable = function->build(block.getColumnsWithTypeAndName());
auto result = executable->execute(block.getColumnsWithTypeAndName(), executable->getResultType(), block.rows(), false);
std::cerr << "output:\n";
debug::headColumn(result);
ASSERT_EQ(result->getUInt(0), result->getUInt(1));
}
TEST(TestFunction, toDateTime64)
{
using namespace DB;
auto & factory = FunctionFactory::instance();
auto function = factory.get("toDateTime64", local_engine::QueryContext::globalContext());
auto d0 = local_engine::STRING();
auto c0 = d0->createColumn();
c0->insert("2025-01-21 12:58:13.106");
auto d1 = local_engine::UINT();
auto c1 = d1->createColumnConst(1, 6);
auto d2 = local_engine::STRING();
auto c2 = d0->createColumnConst(1, "UTC");
ColumnsWithTypeAndName columns
= {ColumnWithTypeAndName(std::move(c0), d0, "string0"), ColumnWithTypeAndName(c1, d1, "int0"), ColumnWithTypeAndName(c2, d2, "tz")};
Block block(columns);
std::cerr << "input:\n";
debug::headBlock(block);
auto executable = function->build(block.getColumnsWithTypeAndName());
auto result = executable->execute(block.getColumnsWithTypeAndName(), executable->getResultType(), block.rows(), false);
std::cerr << "output:\n";
debug::headColumn(result);
DateTime64 time = 0;
{
std::string parsedTimeStamp = "2025-01-21 12:58:13.106";
DB::ReadBufferFromString in(parsedTimeStamp);
readDateTime64Text(time, 6, in, DateLUT::instance("UTC"));
}
Field expected = Field(DecimalField<DateTime64>(time, 6));
ASSERT_EQ((*result.get())[0], expected);
}
TEST(TestFunction, In)
{
using namespace DB;
auto & factory = FunctionFactory::instance();
auto function = factory.get("in", local_engine::QueryContext::globalContext());
auto type0 = DataTypeFactory::instance().get("String");
auto type_set = std::make_shared<DataTypeSet>();
auto column1 = type0->createColumn();
column1->insert("X");
column1->insert("X");
column1->insert("Y");
column1->insert("Z");
SizeLimits limit;
auto set = std::make_shared<Set>(limit, true, false);
Block col1_set_block;
auto col1_set = type0->createColumn();
col1_set->insert("X");
col1_set->insert("Y");
col1_set_block.insert(ColumnWithTypeAndName(std::move(col1_set), type0, "string0"));
set->setHeader(col1_set_block.getColumnsWithTypeAndName());
set->insertFromBlock(col1_set_block.getColumnsWithTypeAndName());
set->finishInsert();
PreparedSets::Hash empty;
auto future_set = std::make_shared<FutureSetFromStorage>(empty, nullptr, std::move(set), std::nullopt);
//TODO: WHY? after https://github.com/ClickHouse/ClickHouse/pull/63723 we need pass 4 instead of 1
auto arg = ColumnSet::create(4, future_set);
ColumnsWithTypeAndName columns
= {ColumnWithTypeAndName(std::move(column1), type0, "string0"), ColumnWithTypeAndName(std::move(arg), type_set, "__set")};
Block block(columns);
std::cerr << "input:\n";
debug::headBlock(block);
auto executable = function->build(block.getColumnsWithTypeAndName());
auto result = executable->execute(block.getColumnsWithTypeAndName(), executable->getResultType(), block.rows(), false);
std::cerr << "output:\n";
debug::headColumn(result);
ASSERT_EQ(result->getUInt(3), 0);
}
TEST(TestFunction, NotIn1)
{
using namespace DB;
auto & factory = FunctionFactory::instance();
auto function = factory.get("notIn", local_engine::QueryContext::globalContext());
auto type0 = DataTypeFactory::instance().get("String");
auto type_set = std::make_shared<DataTypeSet>();
auto column1 = type0->createColumn();
column1->insert("X");
column1->insert("X");
column1->insert("Y");
column1->insert("Z");
SizeLimits limit;
auto set = std::make_shared<Set>(limit, true, false);
Block col1_set_block;
auto col1_set = type0->createColumn();
col1_set->insert("X");
col1_set->insert("Y");
col1_set_block.insert(ColumnWithTypeAndName(std::move(col1_set), type0, "string0"));
set->setHeader(col1_set_block.getColumnsWithTypeAndName());
set->insertFromBlock(col1_set_block.getColumnsWithTypeAndName());
set->finishInsert();
PreparedSets::Hash empty;
auto future_set = std::make_shared<FutureSetFromStorage>(empty, nullptr, std::move(set), std::nullopt);
//TODO: WHY? after https://github.com/ClickHouse/ClickHouse/pull/63723 we need pass 4 instead of 1
auto arg = ColumnSet::create(4, future_set);
ColumnsWithTypeAndName columns
= {ColumnWithTypeAndName(std::move(column1), type0, "string0"), ColumnWithTypeAndName(std::move(arg), type_set, "__set")};
Block block(columns);
std::cerr << "input:\n";
debug::headBlock(block);
auto executable = function->build(block.getColumnsWithTypeAndName());
auto result = executable->execute(block.getColumnsWithTypeAndName(), executable->getResultType(), block.rows(), false);
std::cerr << "output:\n";
debug::headColumn(result);
ASSERT_EQ(result->getUInt(3), 1);
}
TEST(TestFunction, NotIn2)
{
using namespace DB;
auto & factory = FunctionFactory::instance();
auto function = factory.get("in", local_engine::QueryContext::globalContext());
auto type0 = DataTypeFactory::instance().get("String");
auto type_set = std::make_shared<DataTypeSet>();
auto column1 = type0->createColumn();
column1->insert("X");
column1->insert("X");
column1->insert("Y");
column1->insert("Z");
SizeLimits limit;
auto set = std::make_shared<Set>(limit, true, false);
Block col1_set_block;
auto col1_set = type0->createColumn();
col1_set->insert("X");
col1_set->insert("Y");
col1_set_block.insert(ColumnWithTypeAndName(std::move(col1_set), type0, "string0"));
set->setHeader(col1_set_block.getColumnsWithTypeAndName());
set->insertFromBlock(col1_set_block.getColumnsWithTypeAndName());
set->finishInsert();
PreparedSets::Hash empty;
auto future_set = std::make_shared<FutureSetFromStorage>(empty, nullptr, std::move(set), std::nullopt);
//TODO: WHY? after https://github.com/ClickHouse/ClickHouse/pull/63723 we need pass 4 instead of 1
auto arg = ColumnSet::create(4, future_set);
ColumnsWithTypeAndName columns
= {ColumnWithTypeAndName(std::move(column1), type0, "string0"), ColumnWithTypeAndName(std::move(arg), type_set, "__set")};
Block block(columns);
std::cerr << "input:\n";
debug::headBlock(block);
auto executable = function->build(block.getColumnsWithTypeAndName());
auto result = executable->execute(block.getColumnsWithTypeAndName(), executable->getResultType(), block.rows(), false);
auto function_not = factory.get("not", local_engine::QueryContext::globalContext());
auto type_bool = DataTypeFactory::instance().get("UInt8");
ColumnsWithTypeAndName columns2 = {ColumnWithTypeAndName(result, type_bool, "string0")};
Block block2(columns2);
auto executable2 = function_not->build(block2.getColumnsWithTypeAndName());
auto result2 = executable2->execute(block2.getColumnsWithTypeAndName(), executable2->getResultType(), block2.rows(), false);
std::cerr << "output:\n";
debug::headColumn(result2);
ASSERT_EQ(result2->getUInt(3), 1);
}