416 lines
14 KiB
Python
416 lines
14 KiB
Python
#!/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
# 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.
|
|
|
|
"""
|
|
测试sys view相关
|
|
"""
|
|
|
|
import sys
|
|
|
|
sys.path.append("../")
|
|
from lib import palo_config
|
|
from lib import palo_client
|
|
from lib import util
|
|
from lib import palo_logger
|
|
from lib import common
|
|
from data import schema as DATA
|
|
|
|
client = None
|
|
LOG = palo_logger.Logger.getLogger()
|
|
L = palo_logger.StructedLogMessage
|
|
|
|
config = palo_config.config
|
|
baseall_tb = 'test_query_qa.baseall'
|
|
qe_db = 'test_query_qa'
|
|
qe_base_tb = 'baseall'
|
|
|
|
|
|
def setup_module():
|
|
"""
|
|
setUp
|
|
"""
|
|
global client
|
|
client = palo_client.PaloClient(config.fe_host, config.fe_query_port, user=config.fe_user,
|
|
password=config.fe_password)
|
|
client.init()
|
|
|
|
|
|
def execute(line):
|
|
"""execte sql"""
|
|
print(line)
|
|
palo_result = client.execute(line)
|
|
print(palo_result)
|
|
return palo_result
|
|
|
|
|
|
def check2_palo(line1, line2):
|
|
"""
|
|
check2_palo
|
|
:param ret1:
|
|
:param ret2:
|
|
:return:
|
|
"""
|
|
ret1 = execute(line1)
|
|
ret2 = execute(line2)
|
|
util.check(ret1, ret2)
|
|
|
|
|
|
def check_column_list(tb, db, expected_column):
|
|
"""
|
|
check_column_list
|
|
验证desc中的column是不是与期望的一致
|
|
:param tb:
|
|
:param db:
|
|
:param expected_column:
|
|
:return:
|
|
"""
|
|
column_list = client.get_all_columns(tb, db)
|
|
assert len(column_list) == len(expected_column)
|
|
for column in column_list:
|
|
assert column in expected_column
|
|
|
|
|
|
def restart_palo_and_reconnect():
|
|
"""
|
|
todo
|
|
restart_palo_and_reconnect
|
|
重启操作暂时不可用,所以先不放在自动化case里
|
|
fe的持久化测试分为image和journal加载两种形式,暂时是手工执行
|
|
:return:
|
|
"""
|
|
pass
|
|
|
|
|
|
def test_create_and_alter_view():
|
|
"""
|
|
{
|
|
"title": "test_sys_view.test_create_and_alter_view",
|
|
"describe": "test_create_and_alter_view",
|
|
"tag": "function,p1,fuzz"
|
|
}
|
|
"""
|
|
"""test_create_and_alter_view"""
|
|
db_name, table_name, invalied_name_1 = util.gen_name_list()
|
|
line = 'DROP DATABASE IF EXISTS %s' % db_name
|
|
client.execute(line)
|
|
client.create_database(db_name)
|
|
client.use(db_name)
|
|
|
|
view_name = 'baseall_view'
|
|
view_name2 = 'baseall_view_2'
|
|
|
|
# case: view中指定数据库,使用另一个数据库
|
|
line = 'drop view if exists %s' % view_name
|
|
execute(line)
|
|
line = 'create view %s as (select k1,k2 from %s)' % (view_name, baseall_tb)
|
|
execute(line)
|
|
check_column_list(view_name, db_name, ['k1', 'k2'])
|
|
|
|
line = 'drop view if exists %s' % view_name2
|
|
execute(line)
|
|
line = 'create view %s as (select k1,k2 from %s)' % (view_name2, view_name)
|
|
execute(line)
|
|
check_column_list(view_name2, db_name, ['k1', 'k2'])
|
|
|
|
line = 'alter view %s as (select k1,k2,k3 from %s)' % (view_name2, view_name)
|
|
util.assert_return(False, 'Unknown column \'k3\' in \'table list\'',
|
|
execute, line)
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1,k2 from %s order by k1' % baseall_tb
|
|
check2_palo(line1, line2)
|
|
|
|
line = 'alter view %s as (select k1 from %s)' % (view_name, baseall_tb)
|
|
execute(line)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
line = 'alter view %s as (select k1 from %s)' % (view_name2, view_name)
|
|
execute(line)
|
|
check_column_list(view_name2, db_name, ['k1'])
|
|
line = 'alter view %s as (select k1,k2 from %s)' % (view_name2, view_name)
|
|
util.assert_return(False, 'Unknown column \'k2\' in \'table list\'', execute, line)
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1 from %s order by k1' % baseall_tb
|
|
check2_palo(line1, line2)
|
|
|
|
# case: view中不指定数据库,使用当前数据库的其他表
|
|
client.use(qe_db)
|
|
line = 'drop view if exists %s' % view_name
|
|
execute(line)
|
|
line = 'create view %s as (select k1,k2 from %s)' % (view_name, qe_base_tb)
|
|
execute(line)
|
|
check_column_list(view_name, qe_db, ['k1', 'k2'])
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1,k2 from %s order by k1' % qe_base_tb
|
|
check2_palo(line1, line2)
|
|
|
|
line = 'alter view %s as (select k1 from %s)' % (view_name, qe_base_tb)
|
|
execute(line)
|
|
check_column_list(view_name, qe_db, ['k1'])
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1 from %s order by k1' % qe_base_tb
|
|
check2_palo(line1, line2)
|
|
|
|
# restart_palo_and_reconnect()
|
|
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, qe_db, ['k1'])
|
|
|
|
line = 'drop view if exists {0}.{1}'.format(qe_db, view_name)
|
|
execute(line)
|
|
|
|
client.clean(db_name)
|
|
|
|
|
|
def test_create_and_alter_view_with_cte():
|
|
"""
|
|
{
|
|
"title": "test_create_and_alter_view_with_cte",
|
|
"describe": "test_create_and_alter_view_with_cte",
|
|
"tag": "function,p1"
|
|
}
|
|
"""
|
|
"""test_create_and_alter_view_with_cte"""
|
|
db_name, table_name, invalied_name_1 = util.gen_name_list()
|
|
line = 'DROP DATABASE IF EXISTS %s' % db_name
|
|
client.execute(line)
|
|
client.create_database(db_name)
|
|
|
|
view_name = 'baseall_view'
|
|
cte_tb_name = 'test_baseall_cte'
|
|
|
|
# case: 测试没有指定db情况下,使用cte语句建view的情况
|
|
# 目前palo client一定会默认指定一个数据库连接,所以新建一个数据库再drop,来模拟没有指定db连接的情况
|
|
line = 'create database tmp_db'
|
|
execute(line)
|
|
line = 'use tmp_db'
|
|
execute(line)
|
|
line = 'drop database tmp_db'
|
|
execute(line)
|
|
|
|
line = 'create view {0}.{1} as with {2} as (select k1,k2 from {3}) select k1,k2 from {2}'.format(
|
|
db_name, view_name, cte_tb_name, baseall_tb)
|
|
execute(line)
|
|
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name)
|
|
line2 = 'select k1,k2 from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, db_name, ['k1', 'k2'])
|
|
|
|
# restart_palo_and_reconnect()
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, db_name, ['k1', 'k2'])
|
|
|
|
line = 'alter view {0}.{1} as (select k1 from {2})'.format(db_name, view_name, baseall_tb)
|
|
execute(line)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name)
|
|
line2 = 'select k1 from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
# restart_palo_and_reconnect()
|
|
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
|
|
# case: 测试指定db情况下,使用cte语句建view的情况: cte中指定另一个数据库
|
|
client.use(db_name)
|
|
line = 'drop view if exists %s' % view_name
|
|
execute(line)
|
|
line = 'create view {0} as with {1} as (select k1,k2 from {2}) select k1,k2 from {1};'.format(
|
|
view_name, cte_tb_name, baseall_tb)
|
|
execute(line)
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1,k2 from %s order by k1' % baseall_tb
|
|
check2_palo(line1, line2)
|
|
sql = 'select database()'
|
|
execute(sql)
|
|
check_column_list(view_name, db_name, ['k1', 'k2'])
|
|
|
|
line = 'alter view %s as (select k1 from %s)' % (view_name, baseall_tb)
|
|
execute(line)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1 from %s order by k1' % baseall_tb
|
|
check2_palo(line1, line2)
|
|
|
|
# restart_palo_and_reconnect()
|
|
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, db_name, ['k1'])
|
|
|
|
# case: 测试指定db情况下,使用cte语句建view的情况: cte中不指定数据库,使用当前数据库
|
|
client.use(qe_db)
|
|
line = 'drop view if exists %s' % view_name
|
|
execute(line)
|
|
line = 'create view {0} as with {1} as (select k1,k2 from {2}) select k1,k2 from {1};'.format(
|
|
view_name, cte_tb_name, qe_base_tb)
|
|
execute(line)
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1,k2 from %s order by k1' % qe_base_tb
|
|
check2_palo(line1, line2)
|
|
sql = 'select database()'
|
|
execute(sql)
|
|
check_column_list(view_name, qe_db, ['k1', 'k2'])
|
|
|
|
line = 'alter view %s as (select k1 from %s)' % (view_name, qe_base_tb)
|
|
execute(line)
|
|
check_column_list(view_name, qe_db, ['k1'])
|
|
|
|
line1 = 'select * from %s order by k1' % view_name
|
|
line2 = 'select k1 from %s order by k1' % qe_base_tb
|
|
check2_palo(line1, line2)
|
|
|
|
# restart_palo_and_reconnect()
|
|
|
|
check2_palo(line1, line2)
|
|
check_column_list(view_name, qe_db, ['k1'])
|
|
|
|
line = 'drop view if exists {0}.{1}'.format(qe_db, view_name)
|
|
execute(line)
|
|
|
|
client.clean(db_name)
|
|
|
|
|
|
def test_create_and_alter_view_with_sql_mode():
|
|
"""
|
|
{
|
|
"title": "test_create_and_alter_view_with_sql_mode",
|
|
"describe": "test_create_and_alter_view_with_sql_mode, 测试在不同sql mode下新建/修改view,并在不同的sql mode下进行查询, ||的转义结果应该由新建/修改时的sql mode来确定,而不是查询时的sql mode",
|
|
"tag": "function,p1"
|
|
}
|
|
"""
|
|
"""
|
|
test_create_and_alter_view_with_sql_mode
|
|
测试在不同sql mode下新建/修改view,并在不同的sql mode下进行查询
|
|
||的转义结果应该由新建/修改时的sql mode来确定,而不是查询时的sql mode
|
|
"""
|
|
db_name, table_name, invalied_name_1 = util.gen_name_list()
|
|
line = 'DROP DATABASE IF EXISTS %s' % db_name
|
|
client.execute(line)
|
|
client.create_database(db_name)
|
|
client.use(db_name)
|
|
|
|
view_name = 'baseall_view'
|
|
view_name_1 = 'baseall_view_1'
|
|
|
|
# case: 在sql mode=0的时候新建view,这时候的||等价于or
|
|
line = 'set sql_mode=0;'
|
|
execute(line)
|
|
line = 'create view {0} as select (True || False ) from {1}'.format(view_name, baseall_tb)
|
|
execute(line)
|
|
line1 = 'select * from {0}.{1}'.format(db_name, view_name)
|
|
line2 = 'select ((TRUE) OR (FALSE)) from {0}'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
line = 'create view {0} as select k1, (k1>10) || (k2>2) from {1}'.format(view_name_1, baseall_tb)
|
|
execute(line)
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name_1)
|
|
line2 = 'select k1,((k1>10) OR (k2>2)) from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
# case: 由于view是在sql mode=0的时候建的,即使sql mode切换成2,这时候的view的查询结果仍等价于or
|
|
line = 'set sql_mode=2'
|
|
execute(line)
|
|
|
|
line1 = 'select * from {0}.{1}'.format(db_name, view_name)
|
|
line2 = 'select ((TRUE) OR (FALSE)) from {0}'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name_1)
|
|
line2 = 'select k1,((k1>10) OR (k2>2)) from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
# case: 在sql mode=0的时候修改view,这时候的||等价于字符串连接
|
|
line = 'alter view {0} as select (True || False ) from {1}'.format(view_name, baseall_tb)
|
|
execute(line)
|
|
line1 = 'select * from {0}.{1}'.format(db_name, view_name)
|
|
line2 = 'select (concat(TRUE, FALSE)) from {0}'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
line = 'alter view {0} as select k1,(k1>10) || (k2>2) from {1}'.format(view_name_1, baseall_tb)
|
|
execute(line)
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name_1)
|
|
line2 = 'select k1, (concat((k1>10), (k2>2))) from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
# case: 由于view是在sql mode=2的时候修改的,即使sql mode切换成0,这时候的view的查询结果仍等价于字符串连接
|
|
line = 'set sql_mode=0'
|
|
execute(line)
|
|
|
|
line1 = 'select * from {0}.{1}'.format(db_name, view_name)
|
|
line2 = 'select (concat(TRUE, FALSE)) from {0}'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name_1)
|
|
line2 = 'select k1,(concat((k1>10), (k2>2))) from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
# restart_palo_and_reconnect()
|
|
|
|
line1 = 'select * from {0}.{1}'.format(db_name, view_name)
|
|
line2 = 'select (concat(TRUE, FALSE)) from {0}'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
line1 = 'select * from {0}.{1} order by k1'.format(db_name, view_name_1)
|
|
line2 = 'select k1,(concat((k1>10), (k2>2))) from {0} order by k1'.format(baseall_tb)
|
|
check2_palo(line1, line2)
|
|
|
|
client.clean(db_name)
|
|
|
|
|
|
def test_show_view_issue_5812():
|
|
"""
|
|
{
|
|
"title": "test_show_view",
|
|
"describe": "show view正确",
|
|
"tag": "function,p0,fuzz"
|
|
}
|
|
"""
|
|
database_name, table_name, index_name = util.gen_num_format_name_list()
|
|
LOG.info(L('', database_name=database_name,
|
|
table_name=table_name, index_name=index_name))
|
|
client = common.create_workspace(database_name)
|
|
ret = client.create_table(table_name, DATA.tinyint_column_no_agg_list, keys_desc=DATA.unique_key)
|
|
assert ret, 'create table failed'
|
|
sql = 'insert into %s values(1, 2, 3, 4, 5)' % table_name
|
|
ret = client.execute(sql)
|
|
assert ret == (), 'insert date failed'
|
|
view_name = 'test_view'
|
|
sql = 'create view %s as select * from %s' % (view_name, table_name)
|
|
ret = client.execute(sql)
|
|
assert ret == (), 'create view failed'
|
|
sql = 'show view from %s.%s' % (database_name, table_name)
|
|
ret = client.execute(sql)
|
|
assert len(ret) == 1
|
|
client.clean(database_name)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
setup_module()
|