diff --git a/contrib/gms_xmlgen/expected/gms_xmlgen.out b/contrib/gms_xmlgen/expected/gms_xmlgen.out
index 2a8115722..52ee855f6 100644
--- a/contrib/gms_xmlgen/expected/gms_xmlgen.out
+++ b/contrib/gms_xmlgen/expected/gms_xmlgen.out
@@ -1394,6 +1394,64 @@ END;
+-- parameter2 null is the same as false
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setconvertspecialchars(xml_cxt, null);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
+
+
-- error for missing parameter 2
DECLARE
xml_output clob;
@@ -1465,6 +1523,78 @@ END;
+-- set max rows 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setmaxrows(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+
+-- set max rows 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setmaxrows(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+
-- parameter nums error
DECLARE
xml_output clob;
@@ -1703,6 +1833,150 @@ END;
+-- number 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setnullhandling(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-- number 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setnullhandling(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- other numbers > 2, the same as 0
DECLARE
xml_output clob;
@@ -2237,6 +2511,82 @@ END;
+-- set skip row 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
+
+
+-- set skip row 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
+
+
-- set skip row 2
DECLARE
xml_output clob;
@@ -2734,11 +3084,11 @@ xml_output clob;
xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -2799,11 +3149,11 @@ xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setskiprows(xml_cxt, 1);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -2844,11 +3194,11 @@ xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setmaxrows(xml_cxt, 2);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -2908,11 +3258,11 @@ BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setskiprows(xml_cxt, 1);
gms_xmlgen.setmaxrows(xml_cxt, 1);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -2942,6 +3292,80 @@ END;
+1
+-- getnumrowsprocessed with skip rows && max rows
+-- the second getxml should continue from the last
+DECLARE
+processed_row number;
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 0);
+gms_xmlgen.setmaxrows(xml_cxt, 1);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+0
+
+
+
+ 1
+ 1.23456
+ 1.234567
+ true
+ "'<>&char test
+ varchar"'<>&test
+ text test"'<>&
+ FF
+ ABCD
+ 2024-01-02T00:00:00
+
+ 2024-02-03T19:03:04
+ {"a" : 1, "b" : 2}
+
+ abc
+ "'<>&
+ 你好
+
+
+
+
+1
+
+
+
+ 2
+ 2.23456
+ 2.234567
+ false
+ 2"'<>&char test
+ 2varchar"'<>&test
+ 2text test"'<>&
+ EEEE
+ FFFF
+ 2026-03-04T00:00:00
+
+ 2026-05-06T21:13:00
+ [9,8,7,6]
+
+ &^%@
+ "'<>&
+ <&y'">
+
+
+
+
1
-- ok for getnumrowsprocessed context id NULL
DECLARE
@@ -3166,7 +3590,7 @@ GMS_xmlgen.closeContext(ctx);
GMS_output.put_line(ctx::text);
END;
/
-73
+81
DECLARE res XMLType;
BEGIN res := GMS_XMLGEN.GETXMLTYPE('123');
EXCEPTION
diff --git a/contrib/gms_xmlgen/gms_xmlgen--1.0.sql b/contrib/gms_xmlgen/gms_xmlgen--1.0.sql
index 18e94dfd7..585c25e66 100644
--- a/contrib/gms_xmlgen/gms_xmlgen--1.0.sql
+++ b/contrib/gms_xmlgen/gms_xmlgen--1.0.sql
@@ -104,7 +104,7 @@ END;
CREATE OR REPLACE FUNCTION gms_xmlgen.set_convert_special_chars(ctx IN gms_xmlgen.ctxhandle, is_convert IN boolean)
RETURNS void
AS 'MODULE_PATHNAME', 'set_convert_special_chars'
-LANGUAGE C STRICT IMMUTABLE;
+LANGUAGE C IMMUTABLE;
CREATE OR REPLACE PROCEDURE gms_xmlgen.setconvertspecialchars(ctx IN gms_xmlgen.ctxhandle, is_convert IN boolean)
AS
diff --git a/contrib/gms_xmlgen/gms_xmlgen.cpp b/contrib/gms_xmlgen/gms_xmlgen.cpp
index 4125180e4..7c26ffbf9 100644
--- a/contrib/gms_xmlgen/gms_xmlgen.cpp
+++ b/contrib/gms_xmlgen/gms_xmlgen.cpp
@@ -735,12 +735,9 @@ static StringInfo query_to_xml_flat(XMLGenContext *ctx)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_CURSOR), errmsg("cursor \"%s\" does not exist", ctx->query_string)));
}
-
- if (ctx->max_rows < 0) {
- SPI_cursor_fetch(portal, true, LONG_MAX);
- } else {
- SPI_cursor_fetch(portal, true, ctx->skip_rows + ctx->max_rows);
- }
+ check_uint_valid(ctx->current_row + ctx->skip_rows);
+ SPI_cursor_move(portal, true, ctx->current_row + ctx->skip_rows);
+ SPI_cursor_fetch(portal, true, ctx->max_rows >= 0 ? ctx->max_rows : UINT_MAX);
} else {
if (SPI_execute(ctx->query_string, true, 0) != SPI_OK_SELECT) {
pfree_ext(row_tag);
@@ -752,10 +749,9 @@ static StringInfo query_to_xml_flat(XMLGenContext *ctx)
count_rows = (int64)SPI_processed;
check_xml_valid(ctx, count_rows, SPI_tuptable->tupdesc->natts);
- int64 start_now = skip_rows + ctx->current_row;
- if (ctx->max_rows != 0 && count_rows > start_now) {
+ if (ctx->max_rows != 0 && count_rows > 0) {
xml_root_element_start(result, row_set_tag == NULL ? row_tag : row_set_tag, null_flag);
- for (int64 i = skip_rows; i < count_rows; i++) {
+ for (int64 i = 0; i < count_rows; i++) {
SPI_sql_row_to_xml_element(i, result, null_flag, (row_set_tag == NULL || row_tag == NULL) ? NULL : row_tag,
ctx->is_convert_special_chars, ctx->item_tag_name,
(row_set_tag == NULL && row_tag == NULL) ? 0 : 1);
@@ -916,7 +912,7 @@ Datum close_context(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
@@ -943,7 +939,7 @@ Datum convert_xml(PG_FUNCTION_ARGS)
}
int64 flag = 0;
if (!PG_ARGISNULL(1)) {
- flag = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ flag = get_floor_numeric_int64(PG_GETARG_DATUM(1));
}
if (flag < 0 || flag > UINT_MAX) {
@@ -981,7 +977,7 @@ Datum convert_clob(PG_FUNCTION_ARGS)
}
int64 flag = 0;
if (!PG_ARGISNULL(1)) {
- flag = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ flag = get_floor_numeric_int64(PG_GETARG_DATUM(1));
}
char *xmlstr = text_to_cstring((const text *)PG_GETARG_BYTEA_PP(0));
@@ -1013,7 +1009,7 @@ Datum get_num_rows_processed(PG_FUNCTION_ARGS)
{
CHECK_XML_SUPPORT();
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1036,9 +1032,9 @@ Datum get_xml_by_ctx_id(PG_FUNCTION_ARGS)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid gms_xmlgen context id")));
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
- int64 dtd_or_schema = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ int64 dtd_or_schema = get_floor_numeric_int64(PG_GETARG_DATUM(1));
check_uint_valid(dtd_or_schema);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL || ctx->query_string == NULL) {
@@ -1067,7 +1063,7 @@ Datum get_xml_by_query(PG_FUNCTION_ARGS)
}
char *query_str = text_to_cstring(PG_GETARG_TEXT_PP(0));
check_query_string_valid(query_str);
- int64 dtd_or_schema = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ int64 dtd_or_schema = get_floor_numeric_int64(PG_GETARG_DATUM(1));
check_uint_valid(dtd_or_schema);
XMLGenContext *ctx = create_xmlgen_context(0);
ctx->query_string = query_str;
@@ -1141,7 +1137,7 @@ Datum restart_query(PG_FUNCTION_ARGS)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid gms_xmlgen context id")));
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1183,7 +1179,7 @@ Datum set_convert_special_chars(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
bool is_convert = PG_GETARG_BOOL(1);
@@ -1207,9 +1203,9 @@ Datum set_max_rows(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
- int64 max_rows = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ int64 max_rows = get_floor_numeric_int64(PG_GETARG_DATUM(1));
check_uint_valid(max_rows);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1234,9 +1230,9 @@ Datum set_null_handling(PG_FUNCTION_ARGS)
{
CHECK_XML_SUPPORT();
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
- int64 flag = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ int64 flag = get_floor_numeric_int64(PG_GETARG_DATUM(1));
check_uint_valid(flag);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx != NULL) {
@@ -1258,7 +1254,7 @@ Datum set_row_set_tag(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1298,7 +1294,7 @@ Datum set_row_tag(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1340,9 +1336,9 @@ Datum set_skip_rows(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
- int64 skip_rows = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(1));
+ int64 skip_rows = get_floor_numeric_int64(PG_GETARG_DATUM(1));
check_uint_valid(skip_rows);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
@@ -1369,7 +1365,7 @@ Datum use_item_tags_for_coll(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0)) {
PG_RETURN_VOID();
}
- int64 ctx_id = (int64)numeric_int16_internal(PG_GETARG_NUMERIC(0));
+ int64 ctx_id = get_floor_numeric_int64(PG_GETARG_DATUM(0));
check_uint_valid(ctx_id);
XMLGenContext *ctx = get_xmlgen_context(ctx_id);
if (ctx == NULL) {
diff --git a/contrib/gms_xmlgen/gms_xmlgen.h b/contrib/gms_xmlgen/gms_xmlgen.h
index e234cb9ef..728498f92 100644
--- a/contrib/gms_xmlgen/gms_xmlgen.h
+++ b/contrib/gms_xmlgen/gms_xmlgen.h
@@ -15,6 +15,9 @@
? ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value is out of range."))) \
: (void)0)
+#define get_floor_numeric_int64(val) \
+ (int64) numeric_int16_internal(DatumGetNumeric(DirectFunctionCall1(numeric_floor, val)))
+
#define SPACE_PER_INDENTATION 2
#define NULL_FLAG_NULL_ATTR 1
#define NULL_FLAG_EMPTY_TAG 2
diff --git a/contrib/gms_xmlgen/sql/gms_xmlgen.sql b/contrib/gms_xmlgen/sql/gms_xmlgen.sql
index 6d2c678cb..88c3da719 100644
--- a/contrib/gms_xmlgen/sql/gms_xmlgen.sql
+++ b/contrib/gms_xmlgen/sql/gms_xmlgen.sql
@@ -449,6 +449,18 @@ gms_output.put_line(xml_output);
gms_xmlgen.closecontext(xml_cxt);
END;
/
+-- parameter2 null is the same as false
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setconvertspecialchars(xml_cxt, null);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
-- error for missing parameter 2
DECLARE
xml_output clob;
@@ -495,6 +507,30 @@ gms_output.put_line(xml_output);
gms_xmlgen.closecontext(xml_cxt);
END;
/
+-- set max rows 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setmaxrows(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+-- set max rows 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setmaxrows(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
-- parameter nums error
DECLARE
xml_output clob;
@@ -556,6 +592,30 @@ gms_output.put_line(xml_output);
gms_xmlgen.closecontext(xml_cxt);
END;
/
+-- number 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setnullhandling(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+-- number 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setnullhandling(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
-- other numbers > 2, the same as 0
DECLARE
xml_output clob;
@@ -793,6 +853,30 @@ gms_output.put_line(xml_output);
gms_xmlgen.closecontext(xml_cxt);
END;
/
+-- set skip row 1.4, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 1.4);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+-- set skip row 1.9, the same as 1
+DECLARE
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 1.9);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
-- set skip row 2
DECLARE
xml_output clob;
@@ -957,11 +1041,11 @@ xml_output clob;
xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -974,11 +1058,11 @@ xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setskiprows(xml_cxt, 1);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -991,11 +1075,11 @@ xml_cxt gms_xmlgen.ctxhandle;
BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setmaxrows(xml_cxt, 2);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;
@@ -1009,11 +1093,34 @@ BEGIN
xml_cxt := gms_xmlgen.newcontext('select * from t_types');
gms_xmlgen.setskiprows(xml_cxt, 1);
gms_xmlgen.setmaxrows(xml_cxt, 1);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
xml_output := gms_xmlgen.getxml(xml_cxt);
gms_output.put_line(xml_output);
-processed_row:=gms_xmlgen.getnumrowsprocessed(xml_cxt);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+gms_xmlgen.closecontext(xml_cxt);
+END;
+/
+-- getnumrowsprocessed with skip rows && max rows
+-- the second getxml should continue from the last
+DECLARE
+processed_row number;
+xml_output clob;
+xml_cxt gms_xmlgen.ctxhandle;
+BEGIN
+xml_cxt := gms_xmlgen.newcontext('select * from t_types');
+gms_xmlgen.setskiprows(xml_cxt, 0);
+gms_xmlgen.setmaxrows(xml_cxt, 1);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
+gms_output.put_line(processed_row);
+xml_output := gms_xmlgen.getxml(xml_cxt);
+gms_output.put_line(xml_output);
+processed_row := gms_xmlgen.getnumrowsprocessed(xml_cxt);
gms_output.put_line(processed_row);
gms_xmlgen.closecontext(xml_cxt);
END;