
--write_file $MYSQL_TMP_DIR/resultset.xpl
-->import assert_messages.macro
-->import assert_notices.macro

-->varlet %ID% 1
-->macro Prepare_and_cursor_open_wo_res	%OTHER_OPTIONS%	%SQL%
-->varinc %ID% 1
-->noquery_result
-->quiet
-->echo [PREPARE - %SQL%]
Mysqlx.Prepare.Prepare {
  stmt_id: %ID%
  stmt: {
    type: STMT
    stmt_execute: {
      stmt: "%SQL%"
    }
  }
}
-->recvok
-->echo [EXECUTE]
Mysqlx.Cursor.Open {
  cursor_id: %ID%
  stmt {
    type: PREPARE_EXECUTE
    prepare_execute {
      stmt_id: %ID%
    }
  }
  %OTHER_OPTIONS%
}
-->query_result
-->noquiet
-->endmacro


-->macro Cursor_fetch_wo_res	%OTHER_OPTIONS%
-->noquery_result
-->quiet
-->echo [FETCH]
Mysqlx.Cursor.Fetch {
  cursor_id: %ID%
  %OTHER_OPTIONS%
}
-->query_result
-->noquiet
-->endmacro

##
## Purpose of this test is:
#
# * validating that resultsets are in align to the UML flow:
#
#   ...
#   loop has more resultsets or not at end of fetch
#     group resultset
#       loop has more columns
#         server --> client: ColumnMetaData
#       end
#       loop has more rows
#         server --> client: Row
#       end
#     end
#     alt has more resultsets
#       server --> client: FetchDoneMoreResultsets
#     end
#   end
#   loop has more OUT-paramsets or not at end of fetch
#     server --> client: FetchDoneMoreOutParams
#     group resultset
#       loop has more columns
#         server --> client: ColumnMetaData
#       end
#       loop has more rows
#         server --> client: Row
#       end
#     end
#   end
#   alt at end of all resultsets
#     server --> client: FetchDone
#   else cursor is opened
#     server --> client: FetchSuspended
#   end
#   ...
#
# * expecting following notices for SQL prepared-statement:
#
# |Notice\Stmt            |Select |Insert |Update |Delete |
# |-----------------------|-------|-------|-------|-------|
# |ROWS_AFFECTED          |X(0)   |X      |X      |X      |
# |PRODUCED_MESSAGE       |       |       |X      |       |
# |GENERATED_INSERT_ID    |       |X(PK)  |       |       |
# |GENERATED_DOCUMENT_IDS |       |       |       |       |
#
# * cover fetching responses of static SQL and dynamic SQL:
#
#   Resultsets generated by dynamic SQL (for example procedures) can't
#   be buffered by cursors and are executed right away.
#   Because of this issue, Mysqlx.Cursor.Open may return a resultset instead
#   of Mysqlx.Ok.
#
-->echo
-->echo
-->echo ## I. Validate non dynamic SQL statement where Cursor.Fetch is not needed
-->echo #
-->echo # 1. Assert empty resultset, dont get any rows at Cursor.Open.
-->echo # 2. Assert resultset that has less rows than requested by Cursor.Open.
-->echo
-->echo ## II. Validate non dynamic SQL statement where Cursor.Fetch is needed to get all data
-->echo #
-->echo # 1. Assert empty resultset, still try to get at last one row at open
-->echo # 2. Assert resultset that has same amount of rows as requested
-->echo # 3. Assert resultset that has rows grater by one than requested
-->echo # 4. Assert resultset that has two times the amount of rows as requested
-->echo # 5. Assert resultset by fetching the resultset one by one row
-->echo # 6. Assert resultset by fetching the resultset and warnings generated by it
-->echo
-->echo ## III. Validate dynamic SQL statement
-->echo #
-->echo # 1. Assert that cursor open, fetches whole resultset
-->echo #   a. fetch_rows in Cursor.Open is not set
-->echo #   b. fetch_rows in Cursor.Open is set (value doesn't matter).
-->echo # 2. Assert that cursor open, fetches multiple resultsets
-->echo # 3. Assert that cursor open, fetches multiple resultsets with warnings
-->echo
-->echo ## IV. Validate notices
-->echo #
-->echo # 1. Insert stmt
-->echo #   a. Table with primary key (expect notice GENERATED_INSERT_ID)
-->echo #   b. Table without primary key (must not be generate GENERATED_INSERT_ID)
-->echo # 2. Delete stmt
-->echo # 3. Update stmt
-->echo


-->echo
-->echo #
-->echo # I.1
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 1
	SELECT * FROM xtable LIMIT 0;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # I.2
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 1000
	SELECT * FROM xtable;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	5;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.1
callmacro Prepare_and_cursor_open_wo_res
		SELECT * FROM xtable LIMIT 0;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1000;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.2
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 5
	SELECT * FROM xtable LIMIT 5;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	5;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1000;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.3
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 4
	SELECT * FROM xtable LIMIT 5;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	4;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1000;
callmacro Assert_rows	1;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.4
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 2
	SELECT * FROM xtable LIMIT 4;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	2;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1000;
callmacro Assert_rows	2;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.5
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 1
	SELECT * FROM xtable LIMIT 3;
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	1;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1;
callmacro Assert_rows	1;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1;
callmacro Assert_rows	1;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 1;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # II.6
callmacro Prepare_and_cursor_open_wo_res
	
	SELECT 1/prio as col1 FROM xtable;
-->callmacro Assert_metadata	DECIMAL	"col1"
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
## ER_DIVISION_BY_ZERO == 1365
callmacro Assert_notice_warning	WARNING	1365;
callmacro Assert_notice_warning	WARNING	1365;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 2;
callmacro Assert_rows	2;
callmacro Assert_message	Mysqlx.Resultset.FetchSuspended;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

callmacro Cursor_fetch_wo_res	fetch_rows: 4;
callmacro Assert_rows	3;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # III.1.a
callmacro Prepare_and_cursor_open_wo_res
	
	CALL one_resultsets();
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_rows	3;
callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # III.1.b
callmacro Prepare_and_cursor_open_wo_res
	fetch_rows: 1
	CALL one_resultsets();
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_rows	3;
callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # III.2
callmacro Prepare_and_cursor_open_wo_res
	
	CALL two_resultsets();
callmacro Assert_metadata	BYTES	"phrase";
callmacro Assert_rows	3;
callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets;
callmacro Assert_metadata	SINT	"prio";
callmacro Assert_rows	2;
callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets;
callmacro Assert_message	Mysqlx.Resultset.FetchDone;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # III.3
callmacro Prepare_and_cursor_open_wo_res
	
	CALL two_resultsets_with_errors;
-->callmacro Assert_metadata	DECIMAL	"col1"
-->callmacro Assert_rows	5
-->callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets
-->callmacro Assert_metadata	DECIMAL	"col1"
-->callmacro Assert_rows	5
-->callmacro Assert_message	Mysqlx.Resultset.FetchDoneMoreResultsets
-->callmacro Assert_message	Mysqlx.Resultset.FetchDone
## ER_DIVISION_BY_ZERO == 1365
-->callmacro Assert_notice_warning	WARNING	1365
-->callmacro Assert_notice_warning	WARNING	1365
-->callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:0
-->callmacro Assert_message Mysqlx.Sql.StmtExecuteOk


-->echo
-->echo #
-->echo # IV.1.a
callmacro Prepare_and_cursor_open_wo_res
	
	INSERT INTO xtest.xtable_with_pk(description) VALUE('MyCustomRow');
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:1;
callmacro Assert_notice_session_state	GENERATED_INSERT_ID	v_unsigned_int: 2;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # IV.1.b
callmacro Prepare_and_cursor_open_wo_res
	
	INSERT INTO xtest.xtable(phrase, prio) VALUE('MyCustomRow', 100);
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:1;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # IV.2
callmacro Prepare_and_cursor_open_wo_res
	
	DELETE FROM xtest.xtable WHERE prio=100;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:1;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;


-->echo
-->echo #
-->echo # IV.3
callmacro Prepare_and_cursor_open_wo_res
	
	UPDATE xtest.xtable SET phrase='New';
callmacro Assert_notice_session_state	PRODUCED_MESSAGE	type: V_STRING;
callmacro Assert_notice_session_state	ROWS_AFFECTED	v_unsigned_int:5;
callmacro Assert_message Mysqlx.Sql.StmtExecuteOk;

EOF


CREATE SCHEMA IF NOT EXISTS xtest;
USE xtest;

DELIMITER //;

# Data are similar to sample_tables.inc,
# still prio in decremented by one
CREATE PROCEDURE recreate_tables()
BEGIN
  CREATE TABLE IF NOT EXISTS xtable (phrase VARCHAR(30), prio INTEGER);
  TRUNCATE TABLE xtable;
  INSERT INTO xtable (phrase, prio) VALUES ('Alice has a cat', 0);
  INSERT INTO xtable (phrase, prio) VALUES ('Bob has a dog 1', 1);
  INSERT INTO xtable (phrase, prio) VALUES ('Peppa has a teddy', 0);
  INSERT INTO xtable (phrase, prio) VALUES ('Bob has a dog 2', 2);
  INSERT INTO xtable (phrase, prio) VALUES ('Row to delete', 3);
  
  CREATE TABLE IF NOT EXISTS xtable_with_pk (p_id INTEGER AUTO_INCREMENT PRIMARY KEY, description varchar(40));
  TRUNCATE TABLE xtable_with_pk;
  INSERT INTO xtable_with_pk (description) VALUES ('MyRow');
END //

CREATE PROCEDURE one_resultsets()
BEGIN
  SELECT phrase FROM xtable limit 3;
END //

CREATE PROCEDURE two_resultsets()
BEGIN
  SELECT phrase FROM xtable limit 3;
  SELECT prio FROM xtable limit 2;
END //

CREATE PROCEDURE two_resultsets_with_errors()
BEGIN
  SELECT 1/prio as col1 FROM xtable;
  SELECT 1/prio as col1 FROM xtable;
END //

DELIMITER ;//


