polardbxengine/mysql-test/suite/x/t/insert_crud_1.test

789 lines
16 KiB
Plaintext

## ===================================================================
##
## CRUD INSERT SCENARIOS
##
## ===================================================================
## This test runs aims to run insert statementwith mysqlxtest client #
## Test covers #
## - Insert with crud calls #
## - Insert in normal and document table #
## - Insert NULL values #
## - Insert into parent-child(PK-FK) table #
## - Insert with transaction #
## - Insert with lock table #
## - Insert not allowed for user having read permission #
## - Try insert when table lock is acquired by other session(wait) #
## - Two session run insert in parallel #
## - Error case #
## - Try to Insert doc which do not have _id member #
## - Try to insert null for doc column #
## - Try non unique value for _id member #
## - Try projection for DOCUMENT TABLE #
## ===================================================================
# Insert xmessage
# Inserts a row or set of rows in the specified collection or table.
# Arguments
# schema and table
# data_model - relational or document
# projection - list of columns being inserted (for TABLE inserts)
# rows - 1 or more rows with the data to be inserted
# Results
# rows_affected - number of rows that were affected by the operation
# last_insert_id - last value used for the auto-increment field in
# a TABLE INSERT operation (not set for DOCUMENT inserts)
# Mapping
# When inserting into a document collection, the generated INSERT
# statement will look like:
# INSERT INTO schema.table (doc, _id) VALUES (?, JSN_UNQUOTE(JSN_EXTRACT(doc, '$._id')));
# When inserting into a relational table, the generated INSERT will be as:
# INSERT INTO schema.table (projection, ...) VALUES (?, ...);
## Preamble
--source include/xplugin_preamble.inc
--source include/xplugin_create_user.inc
create user readuser@localhost identified by 'readuser';
grant select on *.* to readuser@localhost;
--write_file $MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp
#-- "Create relational TABLE "
-->sql
DROP SCHEMA if EXISTS xplugintest;
CREATE SCHEMA xplugintest DEFAULT CHARSET='utf8';
USE xplugintest;
CREATE TABLE categories (
categoryid int NOT NULL AUTO_INCREMENT,
categoryname varchar(100),
categorydescription varchar(200),
categoryimei tinyint,
categorydecimal decimal(5,2),
categorybool bit(1),
PRIMARY key (categoryid)
);
-->endsql
-->echo Insert multiple rows
Mysqlx.Crud.Insert {
collection {
name: "categories"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "categoryid"
}
projection {
name: "categoryname"
}
projection {
name: "categorydescription"
}
projection {
name: "categoryimei"
}
projection {
name: "categorydecimal"
}
projection {
name: "categorybool"
}
row {
field {
type : LITERAL
literal {
type: V_SINT
v_signed_int: 1
}}
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Sports"
}
}}
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Sports related category"
}
}}
field {
type : LITERAL
literal {
type: V_SINT
v_signed_int: 1
}}
field {
type: LITERAL
literal {
type: V_DOUBLE
v_double: 235.15
}}
field {
type : LITERAL
literal {
type: V_BOOL
v_bool: false
}}
}
row {
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 2
}}
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Entertaiment"
}
}}
field {
type : LITERAL
literal {
type: V_STRING
v_string {
value: "Entertaiment related category"
}
}}
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 2
}}
field {
type: LITERAL
literal {
type: V_DOUBLE
v_double: 156.17
}}
field {
type: LITERAL
literal {
type: V_BOOL
v_bool: true
}}
}
row {
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 18
}}
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Cooking"
}
}}
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Cooking related category"
}
}}
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 18
}}
field {
type: LITERAL
literal {
type: V_DOUBLE
v_double: 116.17
}}
field {
type: LITERAL
literal {
type: V_BOOL
v_bool: true
}}
}
}
#-- Mysqlx.Sql.StmtExecuteOk
-->recvresult
-->sql
SELECT * FROM categories;
-->endsql
-->echo "No auto increment column mentioned in projection"
Mysqlx.Crud.Insert {
collection {
name: "categories"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "categoryname"
}
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "GROUND"
}
}}
}
}
-->recvresult
-->sql
SELECT * FROM categories;
-->endsql
-->echo "Enter NULL values"
Mysqlx.Crud.Insert {
collection {
name: "categories"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "categoryname"
}
row {
field {
type: LITERAL
literal {
type: V_NULL
}}
}
}
-->recvresult
-->sql
SELECT * FROM categories;
-->endsql
-->sql
CREATE TABLE categories_child( col1 INT , col2 JSON ,
FOREIGN KEY (col1) REFERENCES categories(categoryid));
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "categories_child"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "col1"
}
row {
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 18
}}
}
}
-->recvresult
Mysqlx.Crud.Insert {
collection {
name: "categories_child"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "col1"
}
row {
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 100
}}
}
}
-->echo "Insert fails as referencing value not present in parent"
-->expecterror ER_NO_REFERENCED_ROW_2
-->recvresult
-->sql
SELECT * FROM categories_child;
-->endsql
-->echo "Column mismatch"
Mysqlx.Crud.Insert {
collection {
name: "categories_child"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "col1"
}
projection {
name: "col2"
}
row {
field {
type: LITERAL
literal {
type: V_SINT
v_signed_int: 18
}}
}
}
-->expecterror ER_X_BAD_INSERT_DATA
-->recvresult
-->sql
SELECT * FROM categories_child;
DROP TABLE categories_child;
-->endsql
#-- "Create DOCUMENT table "
Mysqlx.Sql.StmtExecute {
stmt: "create_collection"
args {
type: SCALAR
scalar {
type: V_STRING
v_string {
value: "xplugintest"
}
}
}
args {
type: SCALAR
scalar {
type: V_STRING
v_string {
value: "maincollection"
}
}
}
namespace: "xplugin"
}
-->recvresult
-->echo Insert multiple rows into a Document column
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"1\",\n \"name\": \"Omar Bras\", \"id\": \"1\"\n}"
}
}
}}
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"2\",\n \"name\": \"Omar Mex\", \"id\": \"2\"\n}"
}
}}
}
}
-->recvresult
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "Non unique value for _id member of `doc` "
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"3\",\n \"name\": \"Omar Bras\", \"id\": \"3\"\n}"
}
}}
}
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"2\",\n \"name\": \"Omar Mex\", \"id\": \"4\"\n}"
}
}}
}
}
-->expecterror ER_X_DOC_ID_DUPLICATE
-->recvresult
-->echo "Error expected as non unique value for _id provided for member of JSON doc "
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "No _id member for JSON doc"
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"name\": \"Omar Bras\", \"id\": \"3\"\n}"
}
}}
}
}
-->recvresult
-->echo "Error expected as _id member is not provided for JSON doc "
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "projection is not allowed for DOCUMENT table"
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
projection {
name: "doc"
}
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"name\": \"Omar Bras\", \"id\": \"3\"\n}"
}
}}
}
}
-->expecterror ER_X_BAD_PROJECTION
-->recvresult
-->echo "Error expected as projection given for DOCUMENT table "
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "Error when inserting doc as null"
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_NULL
}}
}
}
-->expecterror ER_X_BAD_PROJECTION,ER_X_DOC_ID_MISSING
-->recvresult
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "enter null value in doc member"
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"4\",\n \"name\": \"Jackson\", \"id\": null\n}"
}
}}
}
}
-->recvresult
-->sql
SELECT * FROM maincollection;
-->endsql
-->echo "Insert using transaction"
-->sql
START TRANSACTION;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"5\",\n \"name\": \"Jimmy \", \"id\": null\n}"
}
}}
}
}
-->recvresult
-->sql
SAVEPOINT A;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"6\",\n \"name\": \"Joe\", \"id\": null\n}"
}
}
}}
}
-->recvresult
-->sql
SAVEPOINT B;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"7\",\n \"name\": \"Jacky\", \"id\": null\n}"
}
}}
}
}
-->recvresult
-->sql
ROLLBACK TO SAVEPOINT A;
COMMIT;
-->endsql
-->sql
SELECT * FROM maincollection;
-->endsql
#-- "Insert by acquiring lock"
-->sql
LOCK TABLES maincollection READ;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"7\",\n \"name\": \"Jacky\", \"id\": null\n}"
}
}}
}
}
-->expecterror ER_TABLE_NOT_LOCKED_FOR_WRITE
-->recvresult
-->echo "Error as table is locked with read lock"
-->sql
SELECT * FROM maincollection;
-->endsql
-->sql
UNLOCK TABLES;
LOCK TABLES maincollection WRITE;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "\n{\n \"_id\": \"7\",\n \"name\": \"Jacky\", \"id\": null\n}"
}
}}
}
}
-->recvresult
-->sql
SELECT * FROM maincollection;
UNLOCK TABLES;
-->endsql
EOF
--replace_regex /([0-9a-f]{4})[0-9a-f]{8}([0-9a-f]{16})/\1XXXXXXXX\2/
--exec $MYSQLXTEST -u x_root --password='' --file=$MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp 2>&1
--remove_file $MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp
# "Error : Insert when user has only select access "
--write_file $MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp
-->sql
SET SESSION lock_wait_timeout= 3;
-->endsql
Mysqlx.Crud.Insert {
collection {
name: "categories"
schema: "xplugintest"
}
data_model: TABLE
projection {
name: "categoryname"
}
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "Mountain"
}
}}
}
}
-->expecterror ER_TABLEACCESS_DENIED_ERROR,ER_LOCK_WAIT_TIMEOUT
-->recvresult
-->expecterror ER_SUCCESS,ER_LOCK_WAIT_TIMEOUT
-->sql
SELECT * FROM xplugintest.categories;
-->endsql
EOF
--exec $MYSQLXTEST -u readuser --password='readuser' --file=$MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp 2>&1
# Acquire lock on categories table from mysqltest client
# and try to run insert from mysqlxtest (Error : timeout expected from mysqlxtest)
LOCK TABLES xplugintest.categories WRITE;
--exec $MYSQLXTEST -u x_root --password='' --file=$MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp 2>&1
--remove_file $MYSQL_TMP_DIR/mysqlx-insert_CRUD_1.tmp
UNLOCK TABLES;
# Try run insert from 2 mysqlxtest sessions
DELETE FROM xplugintest.maincollection;
perl;
my $dir = $ENV{'MYSQL_TMP_DIR'};
open ( OUTPUT, ">$dir/mysqlx-in.tmp") ;
$message = <<"END_MESSAGE";
Mysqlx.Crud.Insert {
collection {
name: "maincollection"
schema: "xplugintest"
}
data_model: DOCUMENT
row {
field {
type: LITERAL
literal {
type: V_STRING
v_string {
value: "insert_json_doc"
}
}}
}
}
END_MESSAGE
print OUTPUT "-->sql\n";
print OUTPUT "USE xplugintest;\n";
print OUTPUT "CREATE TABLE IF NOT EXISTS xplugintest.test_table ( col1 INT );\n";
print OUTPUT "-->endsql\n";
for ($i=1001;$i<=1030;$i++) {
if ($i%5 == 0) {
print OUTPUT "-->expecterror ER_SUCCESS,ER_DUP_ENTRY\n";
print OUTPUT "-->sql\n";
print OUTPUT "INSERT INTO maincollection(doc) VALUES ('".'{\"name\":\"name_'.$i.'\"'.' , \"_id\":'.$i."}') \n";
print OUTPUT "-->endsql\n";
}else {
$str = $message;
$replace = '{\"name\":\"name_'.$i.'\"'.' , \"_id\":'.$i.'}';
$find = "insert_json_doc";
$str =~ s/$find/$replace/g;
print OUTPUT "$str\n";
print OUTPUT "-->expecterror ER_SUCCESS,ER_X_DOC_ID_DUPLICATE\n";
print OUTPUT "-->recvresult\n";
}
}
print OUTPUT "-->sql\n";
print OUTPUT "INSERT INTO xplugintest.test_table VALUES (1);\n";
print OUTPUT "-->endsql\n";
close (OUTPUT);
EOF
--exec $MYSQLXTEST -u x_root --password='' --file=$MYSQL_TMP_DIR/mysqlx-in.tmp >$MYSQL_TMP_DIR/mysqlx-out.tmp 2>&1 &
--exec $MYSQLXTEST -u x_root --password='' --file=$MYSQL_TMP_DIR/mysqlx-in.tmp >$MYSQL_TMP_DIR/mysqlx-out2.tmp 2>&1
let $wait_condition= select count(*)=2 from xplugintest.test_table;
--source include/wait_condition.inc
SELECT COUNT(*) FROM xplugintest.maincollection;
## Cleanup
DROP SCHEMA if EXISTS xplugintest;
DROP USER readuser@localhost;
--remove_file $MYSQL_TMP_DIR/mysqlx-in.tmp
--remove_file $MYSQL_TMP_DIR/mysqlx-out2.tmp
--remove_file $MYSQL_TMP_DIR/mysqlx-out.tmp
--source include/xplugin_drop_user.inc