blob: ffae176ffcbb51e9157c665ffae766409a7377ef [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 <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <iostream>
#include <string>
#include "lib/sql_util.h"
#include "gtest/gtest.h"
class TestAlterTable : public ::testing::Test {
public:
TestAlterTable() {}
~TestAlterTable() {}
};
TEST_F(TestAlterTable, TestAlterTableAOColumnDefaultValue) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int, b text, c int)");
util.execute("insert into altable "
"select i, i::text, i from generate_series(1,10) i");
// test add new column into an ao table without default value setting
util.execute("alter table altable add column y int", false);
std::string errstr = "ERROR: ADD COLUMN with no default value in "
"append-only tables is not yet supported.";
EXPECT_STREQ(errstr.c_str(),
util.getPSQL()->getLastResult().substr(0, errstr.size()).c_str());
// test add new column into an ao table having default value setting
util.execute("alter table altable add column x int default 1");
util.query("select a,b,c,x from altable where a=1",
"1|1|1|1|\n");
// test alter column having default value setting
util.execute("alter table altable alter column c set default 10 - 1");
util.execute("insert into altable(a,b) values(11,'11')");
util.query("select a,b,c from altable where a=11",
"11|11|9|\n");
// test alter column dropping default value setting
util.execute("alter table altable alter column c drop default");
util.execute("insert into altable(a,b) values(12,'12')");
util.query("select a,b,c from altable where a=12",
"12|12||\n");
// cleanup
util.execute("drop table altable");
}
TEST_F(TestAlterTable, TestAlterTableAOColumnNOTNULL) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int, b text, c int)");
util.execute("insert into altable "
"select i, i::text, i from generate_series(1,10) i");
// test set not null
util.execute("alter table altable alter column c set not null");
util.execute("insert into altable(a,b) values(13,'13')", false);
std::string errstr = "ERROR: null value in column \"c\" violates "
"not-null constraint";
EXPECT_STREQ(errstr.c_str(),
util.getPSQL()->getLastResult().substr(0, errstr.size()).c_str());
// test drop not null
util.execute("alter table altable alter column c drop not null");
util.execute("insert into altable(a,b) values(13,'13')");
util.query("select a,b,c from altable where a=13",
"13|13||\n");
// cleanup
util.execute("drop table altable");
}
TEST_F(TestAlterTable, TestAlterTableAOColumnConstraint) {
hawq::test::SQLUtility util;
bool orcaon = false;
if (util.getGUCValue("optimizer") == "on") {
std::cout << "NOTE: TestAlterTable.TestAlterTableAOColumnConstraint "
"uses answer for optimizer on" << std::endl;
orcaon = true;
}
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int, b text, c int)");
util.execute("insert into altable "
"select i, i::text, i from generate_series(1,10) i");
// test , constaint is broken by existing rows
util.execute("alter table altable "
"add constraint c_check check (c<10)", false);
std::string errstr = "ERROR: check constraint \"c_check\" "
"is violated by some row";
EXPECT_STREQ(errstr.c_str(),
util.getPSQL()->getLastResult().substr(0, errstr.size()).c_str());
// test, new row breaks existing contraint
util.execute("alter table altable add constraint c_check check (c>0)");
util.execute("insert into altable(a,b,c) values(11,'11',-11)", false);
if (orcaon) {
errstr = "ERROR: One or more assertions failed";
}
else {
errstr = "ERROR: new row for relation \"altable\" "
"violates check constraint \"c_check\"";
}
EXPECT_STREQ(errstr.c_str(),
util.getPSQL()->getLastResult().substr(0, errstr.size()).c_str());
if (orcaon) {
std::string errdetail = "DETAIL: Check constraint c_check for table "
"altable was violated";
std::string::size_type find = util.getPSQL()->getLastResult().find(errdetail);
EXPECT_NE(find, std::string::npos);
}
// test, drop constraint
util.execute("alter table altable drop constraint c_check");
util.execute("insert into altable(a,b,c) values(11,'11',-11)");
util.query("select a,b,c from altable where a=11",
"11|11|-11|\n");
// cleanup
util.execute("drop table altable");
}
TEST_F(TestAlterTable, TestAlterTableAOColumnMisc) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int, b text, c int)");
util.execute("insert into altable "
"select i, i::text, i from generate_series(1,10) i");
util.execute("alter table altable alter column c set statistics 100");
util.execute("alter table altable alter column b set storage plain");
util.execute("insert into altable(a,b,c) values(11,'11',11)");
util.query("select a,b,c from altable where a=11",
"11|11|11|\n");
// drop column
util.execute("alter table altable drop column b");
util.query("select a,c from altable where a=1", "1|1|\n");
// change column type from int to bigint
util.execute("alter table altable alter column c type bigint");
// miscs ( should add more to verify the changes after successfully changed
// the target table
util.execute("alter table altable set without oids");
util.execute("alter table altable set (fillfactor=90)", false);
std::string errstr = "ERROR: altering reloptions for append only tables "
"is not permitted";
EXPECT_STREQ(errstr.c_str(),
util.getPSQL()->getLastResult().substr(0, errstr.size()).c_str());
// cleanup
util.execute("drop table altable");
}
TEST_F(TestAlterTable, TestAlterTableAODropColumn) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int, b text, c int)");
util.execute("insert into altable "
"select i, i::text, i from generate_series(1,10) i");
// test set not null
util.execute("alter table altable drop column b");
util.query("select a,c from altable where a=10","10|10|\n");
// cleanup
util.execute("drop table altable");
}
TEST_F(TestAlterTable, TestAlterTableOwner) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("drop user if exists altuser");
// test
util.execute("create user altuser");
util.execute("create table altable (a,b) as values(1,10),(2,20)");
util.execute("alter table altable owner to altuser");
util.execute("set role altuser");
util.execute("insert into altable(a,b) values(3,30)");
util.execute("reset role");
// cleanup
util.execute("drop table altable");
util.execute("drop user altuser");
}
TEST_F(TestAlterTable, TestAlterTableAddColumn) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists tmp");
// test
util.execute("create table tmp (initial int4)");
util.execute("ALTER TABLE tmp ADD COLUMN a int4 default 3");
util.execute("ALTER TABLE tmp ADD COLUMN b name default 'Alan Turing'");
util.execute("ALTER TABLE tmp ADD COLUMN c text default 'Pivotal'");
util.execute("ALTER TABLE tmp ADD COLUMN d float8 default 0");
util.execute("ALTER TABLE tmp ADD COLUMN e float4 default 0");
util.execute("ALTER TABLE tmp ADD COLUMN f int2 default 0");
util.execute("ALTER TABLE tmp ADD COLUMN g polygon default "
"'(1,1),(1,2),(2,2)'::polygon");
util.execute("ALTER TABLE tmp ADD COLUMN h abstime default null");
util.execute("ALTER TABLE tmp ADD COLUMN i char default 'P'");
util.execute("set datestyle=ISO,DMY;"
"ALTER TABLE tmp ADD COLUMN j abstime[] "
"default ARRAY['2/2/2013 4:05:06'::abstime, "
"'2/2/2013 5:05:06'::abstime]");
util.execute("ALTER TABLE tmp ADD COLUMN k int4 default 0");
util.execute("ALTER TABLE tmp ADD COLUMN l tid default '(0,1)'::tid");
util.execute("ALTER TABLE tmp ADD COLUMN m xid default '0'::xid");
util.execute("ALTER TABLE tmp ADD COLUMN n oidvector "
"default '0 0 0 0'::oidvector");
util.execute("ALTER TABLE tmp ADD COLUMN p smgr "
"default 'magnetic disk'::smgr");
util.execute("ALTER TABLE tmp ADD COLUMN q point default '(0,0)'::point");
util.execute("ALTER TABLE tmp ADD COLUMN r lseg default '(0,0),(1,1)'::lseg");
util.execute("ALTER TABLE tmp ADD COLUMN s path default '(1,1),(1,2),(2,2)'::path");
util.execute("ALTER TABLE tmp ADD COLUMN t box default box(circle '((0,0), 2.0)')");
util.execute("set datestyle=ISO,DMY;"
"ALTER TABLE tmp ADD COLUMN u tinterval "
"default tinterval('2/2/2013 4:05:06', '2/2/2013 5:05:06')");
util.execute("set datestyle=ISO,DMY;"
"ALTER TABLE tmp ADD COLUMN v timestamp "
"default '2/2/2013 4:05:06'::timestamp");
util.execute("ALTER TABLE tmp ADD COLUMN w interval default '3 4:05:06'::interval");
util.execute("ALTER TABLE tmp ADD COLUMN x float8[] default ARRAY[0, 0, 0]");
util.execute("ALTER TABLE tmp ADD COLUMN y float4[] default ARRAY[0, 0, 0]");
util.execute("ALTER TABLE tmp ADD COLUMN z int2[] default ARRAY[0, 0, 0]");
util.execSQLFile("catalog/sql/alter-table-addcol-insert-alltypes.sql",
"catalog/ans/alter-table-addcol-insert-alltypes.ans");
// cleanup
util.execute("drop table tmp");
}
TEST_F(TestAlterTable, TestAlterTableDistributed) {
hawq::test::SQLUtility util;
// prepare
util.execute("drop table if exists altable");
util.execute("create table altable (a int)");
util.execute("insert into altable select generate_series(1,1000);");
// set bucket_number and do distributed
util.execute("set default_hash_table_bucket_number=8;");
util.execute("alter table altable set with(reorganize=true) distributed by (a);");
// check access ok
util.execSQLFile("catalog/sql/alter-table-distributed.sql",
"catalog/ans/alter-table-distributed.ans");
// set another bucket_number and check again
util.execute("set default_hash_table_bucket_number=11;");
util.execute("alter table altable set with(reorganize=true) distributed by (a);");
// check access ok
util.execSQLFile("catalog/sql/alter-table-distributed.sql",
"catalog/ans/alter-table-distributed.ans");
// cleanup
util.execute("drop table altable");
}