You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
proxysql/test/tap/tests/clickhouse_php_conn-t.php

275 lines
9.2 KiB

#!/usr/bin/env php
<?php
/**
* Test written in a TAP alike format checking that PHP connector is able to connect to ClickHouse through
* ProxySQL and that it receives the correct types for the supported types. The test operations are:
*
* 1. Create a connection to ClickHouse through ProxySQL using PHP connector.
* 2. Creates a table holding the supported types: [EventDate,DateTime,TINTYINT(Int8),SMALLINT(Int16),INT(Int32),BIGINT(Int64),FLOAT(Float32),DOUBLE(Float64),DECIMAL(Decimal64)]
* 3. Insert data in the table through: INSERT * SELECT.
* 4. Query the table data checking:
* 4.1 - The types correctly matches the expected ones (not mangled into 'string').
* 4.2 - NULL types are supported and are properly represented and retrieved.
* 4.3 - Values are properly received, being able to be casted and compared with inserting values.
*/
error_reporting(E_ALL ^ E_NOTICE);
$username="cuser";
$password="cpass";
$port=6090;
#$username="sbtest1";
#$password="sbtest1";
#$port=13306;
$admin_user = getenv("TAP_ADMINUSERNAME");
$admin_user = $admin_user == false ? "admin" : $admin_user;
$admin_pass = getenv("TAP_ADMINPASSWORD");
$admin_pass = $admin_pass == false ? "admin" : $admin_pass;
$admin_port = getenv("TAP_ADMINPORT");
$admin_port = $admin_port == false ? 6032 : $admin_port;
echo ":: Creating ProxySQL Admin connection...".PHP_EOL;
$proxy_admin = new mysqli("127.0.0.1", $admin_user, $admin_pass, "", $admin_port);
if ($proxy_admin->connect_errno) {
die("PorxySQL connect failed: " . $proxy->connect_error);
}
echo ":: ProxySQL ProxySQL Admin connection completed".PHP_EOL;
echo ":: Creating required users for test...".PHP_EOL;
$proxy_admin->query("INSERT OR REPLACE INTO clickhouse_users (username,password,active,max_connections) VALUES ('{$username}','{$password}',1,100)");
$proxy_admin->query("LOAD CLICKHOUSE USERS TO RUNTIME");
echo ":: Finished creating users".PHP_EOL;
echo ":: Creating ProxySQL connection...".PHP_EOL;
$proxy = new mysqli("127.0.0.1", $username, $password, "", $port);
if ($proxy->connect_errno) {
die("PorxySQL connect failed: " . $proxy->connect_error);
}
echo ":: ProxySQL connection completed".PHP_EOL;
echo ":: Starting schema and table creation...".PHP_EOL;
if ($port !== 6090) {
$proxy->query("CREATE DATABASE IF NOT EXISTS test");
$proxy->query("USE test");
$proxy->query("DROP TABLE IF EXISTS types_table");
$proxy->query("CREATE TABLE IF NOT EXISTS types_table (EventDate DATE, DateTime DATETIME, col1 TINYINT, col2 SMALLINT, col3 INT, col4 BIGINT, col5 FLOAT, col6 DOUBLE, col7 Decimal)");
echo ":: Inserting data directly to MySQL".PHP_EOL;
$proxy->query("INSERT INTO types_table SELECT NOW(),NOW(),127,-32768,2147483647,9223372036854775801,340282346638528859811704183484516925440.0,340282346638528859811704183484516925440.0, 300.0");
echo ":: Fetching inserted data".PHP_EOL;
$result = $proxy->query("SELECT EventDate,DateTime,col1,col2,col3,col4,col5,round(col6,0),col7 FROM types_table");
while ($row = mysqli_fetch_row($result)) {
echo " * ROW: [";
foreach ($row as $val) {
echo $val.",";
}
echo "]".PHP_EOL;
}
echo ":: Finished operations on MySQL conn".PHP_EOL;
exit(0);
} else {
$proxy->query("CREATE DATABASE IF NOT EXISTS test");
$proxy->query("USE test");
$proxy->query("DROP TABLE IF EXISTS types_table");
$proxy->query("CREATE TABLE IF NOT EXISTS types_table (EventDate DATE, DateTime DATETIME, col1 UInt8, col2 Int16, col3 Int32, col4 Int64, col5 Nullable(Float32), col6 Float64, col7 Decimal64(3)) ENGINE=MergeTree(EventDate, (EventDate), 8192)");
}
$shortName = exec('date +%Z');
$longName = timezone_name_from_abbr($shortName);
$timezone = timezone_open($longName);
$datetime_db = date_create("now", timezone_open("UTC"));
$timezone_off = timezone_offset_get($timezone, $datetime_db);
$cur_date = date("Y-m-d");
$cur_datetime = date("Y-m-d H:i:s");
echo ":: Schema and table creation completed".PHP_EOL;
$exp_rows = [
[
"insert" => "INSERT INTO types_table SELECT '{$cur_date}','{$cur_datetime}',127,-32768,2147483647,9223372036854775802,340282346638528859811704183484516925440,340282346638528859811704183484516925440.0, 300.1",
"select" => "SELECT EventDate,DateTime,col1,col2,col3,col4,col5,round(col6,0),col7 FROM types_table",
"types" => [10, 12, 1, 2, 3, 8, 4, 5, 246],
"vals" => [$cur_date, $cur_datetime, 127, -32768, 2147483647, 9223372036854775802, 340282346638528859811704183484516925440, 340282346638528859811704183484516925440.0, '300.100']
],
[
"insert" => "INSERT INTO types_table SELECT '{$cur_date}','{$cur_datetime}',127,-32768,2147483647,9223372036854775803,1.2,340282346638528859811704183484516925440.0, 300.2",
"select" => "SELECT EventDate,DateTime,col1,col2,col3,col4,ROUND(col5,20),round(col6,0),col7 FROM types_table",
"types" => [10, 12, 1, 2, 3, 8, 4, 5, 246],
"vals" => [$cur_date, $cur_datetime, 127, -32768, 2147483647, 9223372036854775803, 1.2, 340282346638528859811704183484516925440.0, '300.200']
],
[
"insert" => "INSERT INTO types_table SELECT '{$cur_date}','{$cur_datetime}',127,-32768,2147483647,9223372036854775804,NULL,340282346638528859811704183484516925440.0, 300.3",
"select" => "SELECT EventDate,DateTime,col1,col2,col3,col4,col5,round(col6,0),col7 FROM types_table",
"types" => [10, 12, 1, 2, 3, 8, 4, 5, 246],
"vals" => [$cur_date, $cur_datetime, 127, -32768, 2147483647, 9223372036854775804, NULL, 340282346638528859811704183484516925440.0, '300.300']
]
];
echo ":: Checking expected data definition...".PHP_EOL;
foreach ($exp_rows as $row) {
$c_row_types = count($row["types"]);
$c_row_vals = count($row["vals"]);
if ($c_row_types !== $c_row_vals) {
echo " * Invalid exp row definition for query '{$row["select"]}'. Expected type count '{$c_row_types}' != '{$c_row_vals}'".PHP_EOL;
exit(1);
}
}
echo ":: Checking expected data completed".PHP_EOL;
$exit_code = 0;
$count = 0;
foreach ($exp_rows as $exp_row) {
echo ":: Performing operation for payload num '$count'".PHP_EOL;
echo " * Issuing INSERT query '{$exp_row["insert"]}'".PHP_EOL;
$proxy->query($exp_row["insert"]);
echo " * Issuing SELECT query '{$exp_row["select"]}'".PHP_EOL;
$result = $proxy->query($exp_row["select"]);
/* Get field information for all columns */
$finfo = $result->fetch_fields();
echo " * START: Received columns info".PHP_EOL;
$act_col_defs = array();
foreach ($finfo as $val) {
printf(" - Name: %s\n", $val->name);
printf(" - Table: %s\n", $val->table);
printf(" - Max. Len: %d\n", $val->max_length);
printf(" - Length: %d\n", $val->length);
printf(" - charsetnr: %d\n", $val->charsetnr);
printf(" - Flags: %d\n", $val->flags);
printf(" - Type: %d\n\n", $val->type);
array_push($act_col_defs, $val);
}
echo " * END: Received columns info".PHP_EOL;
echo ":: Checking fetched data...".PHP_EOL;
$fetch_rows = array();
while ($row = mysqli_fetch_row($result)) {
array_push($fetch_rows, $row);
}
$c_exp_rows = 1;
$c_fetch_rows = count($fetch_rows);
if ($c_exp_rows !== $c_fetch_rows) {
echo "Expected received row number doesn't match actual received rows - exp: {$c_exp_rows}, act: {$c_fetch_rows}".PHP_EOL;
exit(1);
}
$types_match = true;
$type_count = 0;
foreach ($act_col_defs as $act_col_def) {
$act_type = $act_col_def->type;
$exp_type = $exp_row["types"][$type_count];
$type_match = $act_type === $exp_type;
if ($type_match) {
$ok_msg = "ok";
} else {
$ok_msg = "not ok";
}
echo " {$ok_msg} - Type match result for column '{$act_col_def->name}' was '{$type_match}'.";
echo " ExpType: '{$exp_type}'. ActType '{$act_type}'".PHP_EOL;
$type_count += 1;
$types_match &= $type_match;
}
echo PHP_EOL;
$vals_match = true;
$val_count = 0;
foreach ($fetch_rows as $row) {
foreach ($row as $val) {
$col_name = $act_col_defs[$val_count]->name;
$exp_val = $exp_row["vals"][$val_count];
$exp_type = $exp_row["types"][$val_count];
if (is_null($exp_val) == false) {
if ($exp_type == 1 || $exp_type == 2 || $exp_type == 3 || $exp_type == 8) {
$cast_val = (int)$val;
} else if ($exp_type == 4 | $exp_type == 5) {
$cast_val = (float)$val;
} else if ($exp_type == 12) {
$timestamp = strtotime($val) - $timezone_off;
$cast_val = date("Y-m-d H:i:s", $timestamp);
} else {
$cast_val = $val;
}
} else {
$cast_val = $val;
}
$val_match = $exp_val === $cast_val;
if ($val_match) {
$ok_msg = "ok";
} else {
$ok_msg = "not ok";
}
echo " {$ok_msg} - Value result match for column '{$col_name}' was '{$val_match}'.";
echo " ExpVal: '{$exp_val}'. ActVal '{$cast_val}'".PHP_EOL;
$vals_match &= $val_match;
$val_count += 1;
}
$val_count = 0;
break;
}
$count += 1;
echo ":: Cleaning up table before next queries...".PHP_EOL;
$proxy->query("ALTER TABLE types_table DELETE WHERE 1=1");
$result = $proxy->query("SELECT COUNT(*) FROM types_table");
$row = mysqli_fetch_row($result);
echo ":: Waiting for table cleaning";
while ($row[0] != 0) {
echo ".";
sleep(1);
$result = $proxy->query("SELECT COUNT(*) FROM types_table");
$row = mysqli_fetch_row($result);
}
echo PHP_EOL;
echo ":: Table cleaning completed".PHP_EOL;
$exit_code |= !($types_match & $vals_match);
}
$proxy->query("DROP DATABASE IF EXISTS test");
$result->free();
exit($exit_code);
?>