#!/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()