agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v32 10/11] Preserve pg_stat_file() isdir.. 10+ messages / 2 participants [nested] [flat]
* [PATCH v32 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index bef20178ea6..7171357f442 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -471,11 +471,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -497,7 +498,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -509,11 +510,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 346c4c577c0..998f5164170 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6375,16 +6375,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 8b26b5811e4..1a11661d9fe 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -263,8 +263,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --Bne5rrxQd65beI7a Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v32-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v31 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index bef20178ea..7171357f44 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -471,11 +471,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -497,7 +498,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -509,11 +510,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 61b39094d0..4508f69f48 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6375,16 +6375,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 8b26b5811e..1a11661d9f 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -263,8 +263,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --qZVVwWJgpX9Jzs7f Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v31-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v33 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 8401743efad..9f5c2bed151 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -471,11 +471,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -497,7 +498,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -509,11 +510,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 8f4c87c724d..b81fbd04bc4 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6375,16 +6375,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 6a6cec31a2e..1695bf4a3a7 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -305,8 +305,8 @@ select * from pg_ls_waldir() limit 0; (0 rows) select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.1 --9CzcV6dAFIr7O1Ie Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v33-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v30 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 10bcb0b049..0f42714d90 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -470,11 +470,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -496,7 +497,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -508,11 +509,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 176501a87a..dfe27d2e3e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6303,16 +6303,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index db3d64de3b..349a549744 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -234,8 +234,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --ZwgA9U+XZDXt4+m+ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v30-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v25 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 6e8898029f..5c4a7f748d 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -468,11 +468,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -494,7 +495,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -506,11 +507,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); tuple_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 414b087756..a75929cb92 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6203,16 +6203,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 5b87ab4844..e1e9ced303 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -221,8 +221,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --SBikYMzjhZGK9d4p Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v25-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v26 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 0855f5e88e..2ec44863b8 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -468,11 +468,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -494,7 +495,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -506,11 +507,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 5d80cfa6c1..ee0c5eccec 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6203,16 +6203,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 5b87ab4844..e1e9ced303 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -221,8 +221,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --yKkOmjQZXRsvHRX8 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v26-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v27 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index af666d658b..ff31e38484 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -471,11 +471,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -497,7 +498,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -509,11 +510,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 0a9d1e46bd..89ce701654 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6302,16 +6302,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index db3d64de3b..349a549744 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -234,8 +234,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --19uQFt6ulqmgNgg1 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v27-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v28 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index af666d658b..ff31e38484 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -471,11 +471,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -497,7 +498,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -509,11 +510,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); values_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 2fc1793b5a..a768176032 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6319,16 +6319,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index db3d64de3b..349a549744 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -234,8 +234,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --vk/v8fjDPiDepTtA Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v28-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v24 10/11] Preserve pg_stat_file() isdir.. @ 2020-11-29 04:29 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Justin Pryzby @ 2020-11-29 04:29 UTC (permalink / raw) ..per Tom's suggestion --- src/backend/utils/adt/genfile.c | 15 ++++++++++++--- src/include/catalog/pg_proc.dat | 12 ++++++------ src/test/regress/expected/misc_functions.out | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 6e8898029f..5c4a7f748d 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -468,11 +468,12 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_PP(0); char *filename; struct stat fst; - Datum values[6]; - bool nulls[6]; + Datum values[7]; + bool nulls[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; + char type; /* check the optional argument */ if (PG_NARGS() == 2) @@ -494,7 +495,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -506,11 +507,19 @@ pg_stat_file(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 5, "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, + "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "type", CHAROID, -1, 0); BlessTupleDesc(tupdesc); memset(nulls, false, sizeof(nulls)); tuple_from_stat(&fst, filename, values, nulls); + + /* For pg_stat_file, keep isdir column for backward compatibility */ + type = DatumGetChar(values[5]); + values[5] = BoolGetDatum(type == 'd'); /* isdir */ + values[6] = CharGetDatum(type); /* file type */ + tuple = heap_form_tuple(tupdesc, values, nulls); pfree(filename); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 12a7391e73..d472afcf71 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6202,16 +6202,16 @@ { oid => '2623', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{filename,size,access,modification,change,creation,type}', + proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,o,o,o,o,o,o,o}', + proargnames => '{filename,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file_1arg' }, { oid => '3307', descr => 'get information about file', proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record', proargtypes => 'text bool', - proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,char}', - proargmodes => '{i,i,o,o,o,o,o,o}', - proargnames => '{filename,missing_ok,size,access,modification,change,creation,type}', + proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool,char}', + proargmodes => '{i,i,o,o,o,o,o,o,o}', + proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir,type}', prosrc => 'pg_stat_file' }, { oid => '2624', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 5b87ab4844..e1e9ced303 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -221,8 +221,8 @@ select pg_ls_dir('does not exist'); -- fails with missingok=false ERROR: could not open directory "does not exist": No such file or directory -- Check that expected columns are present select * from pg_stat_file('.') limit 0; - size | access | modification | change | creation | type -------+--------+--------------+--------+----------+------ + size | access | modification | change | creation | isdir | type +------+--------+--------------+--------+----------+-------+------ (0 rows) -- This tests the missing_ok parameter, which causes pg_ls_tmpdir to succeed even if the tmpdir doesn't exist yet -- 2.17.0 --mPTHnM80CEnHQ2WJ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v24-0011-Add-recursion-option-in-pg_ls_dir_files.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
* [PATCH v2.15 12/18] aio: Add IO queue helper @ 2025-03-18 18:40 Andres Freund <[email protected]> 0 siblings, 0 replies; 10+ messages in thread From: Andres Freund @ 2025-03-18 18:40 UTC (permalink / raw) This is likely never going to anywhere - Thomas Munro is working on something more complete. But I needed a way to exercise aio for checkpointer / bgwriter. --- src/include/storage/io_queue.h | 33 +++++ src/backend/storage/aio/Makefile | 1 + src/backend/storage/aio/io_queue.c | 204 ++++++++++++++++++++++++++++ src/backend/storage/aio/meson.build | 1 + src/tools/pgindent/typedefs.list | 2 + 5 files changed, 241 insertions(+) create mode 100644 src/include/storage/io_queue.h create mode 100644 src/backend/storage/aio/io_queue.c diff --git a/src/include/storage/io_queue.h b/src/include/storage/io_queue.h new file mode 100644 index 00000000000..92b1e9afe6f --- /dev/null +++ b/src/include/storage/io_queue.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * io_queue.h + * Mechanism for tracking many IOs + * + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/io_queue.h + * + *------------------------------------------------------------------------- + */ +#ifndef IO_QUEUE_H +#define IO_QUEUE_H + +#include "storage/aio_types.h" + +struct IOQueue; +typedef struct IOQueue IOQueue; + +struct PgAioWaitRef; + +extern IOQueue *io_queue_create(int depth, int flags); +extern void io_queue_track(IOQueue *ioq, const PgAioWaitRef *iow); +extern void io_queue_wait_one(IOQueue *ioq); +extern void io_queue_wait_all(IOQueue *ioq); +extern bool io_queue_is_empty(IOQueue *ioq); +extern void io_queue_reserve(IOQueue *ioq); +extern PgAioHandle *io_queue_acquire_io(IOQueue *ioq); +extern void io_queue_free(IOQueue *ioq); + +#endif /* IO_QUEUE_H */ diff --git a/src/backend/storage/aio/Makefile b/src/backend/storage/aio/Makefile index 3f2469cc399..86fa4276fda 100644 --- a/src/backend/storage/aio/Makefile +++ b/src/backend/storage/aio/Makefile @@ -15,6 +15,7 @@ OBJS = \ aio_init.o \ aio_io.o \ aio_target.o \ + io_queue.o \ method_io_uring.o \ method_sync.o \ method_worker.o \ diff --git a/src/backend/storage/aio/io_queue.c b/src/backend/storage/aio/io_queue.c new file mode 100644 index 00000000000..526aa1d5e06 --- /dev/null +++ b/src/backend/storage/aio/io_queue.c @@ -0,0 +1,204 @@ +/*------------------------------------------------------------------------- + * + * io_queue.c + * AIO - Mechanism for tracking many IOs + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/storage/aio/io_queue.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "lib/ilist.h" +#include "storage/aio.h" +#include "storage/io_queue.h" +#include "utils/resowner.h" + + + +typedef struct TrackedIO +{ + PgAioWaitRef iow; + dlist_node node; +} TrackedIO; + +struct IOQueue +{ + int depth; + int unsubmitted; + + bool has_reserved; + + dclist_head idle; + dclist_head in_progress; + + TrackedIO tracked_ios[FLEXIBLE_ARRAY_MEMBER]; +}; + + +IOQueue * +io_queue_create(int depth, int flags) +{ + size_t sz; + IOQueue *ioq; + + sz = offsetof(IOQueue, tracked_ios) + + sizeof(TrackedIO) * depth; + + ioq = palloc0(sz); + + ioq->depth = 0; + + for (int i = 0; i < depth; i++) + { + TrackedIO *tio = &ioq->tracked_ios[i]; + + pgaio_wref_clear(&tio->iow); + dclist_push_tail(&ioq->idle, &tio->node); + } + + return ioq; +} + +void +io_queue_wait_one(IOQueue *ioq) +{ + /* submit all pending IO before waiting */ + pgaio_submit_staged(); + + while (!dclist_is_empty(&ioq->in_progress)) + { + /* FIXME: Should we really pop here already? */ + dlist_node *node = dclist_pop_head_node(&ioq->in_progress); + TrackedIO *tio = dclist_container(TrackedIO, node, node); + + pgaio_wref_wait(&tio->iow); + dclist_push_head(&ioq->idle, &tio->node); + } +} + +void +io_queue_reserve(IOQueue *ioq) +{ + if (ioq->has_reserved) + return; + + if (dclist_is_empty(&ioq->idle)) + io_queue_wait_one(ioq); + + Assert(!dclist_is_empty(&ioq->idle)); + + ioq->has_reserved = true; +} + +PgAioHandle * +io_queue_acquire_io(IOQueue *ioq) +{ + PgAioHandle *ioh; + + io_queue_reserve(ioq); + + Assert(!dclist_is_empty(&ioq->idle)); + + if (!io_queue_is_empty(ioq)) + { + ioh = pgaio_io_acquire_nb(CurrentResourceOwner, NULL); + if (ioh == NULL) + { + /* + * Need to wait for all IOs, blocking might not be legal in the + * context. + * + * XXX: This doesn't make a whole lot of sense, we're also + * blocking here. What was I smoking when I wrote the above? + */ + io_queue_wait_all(ioq); + ioh = pgaio_io_acquire(CurrentResourceOwner, NULL); + } + } + else + { + ioh = pgaio_io_acquire(CurrentResourceOwner, NULL); + } + + return ioh; +} + +void +io_queue_track(IOQueue *ioq, const struct PgAioWaitRef *iow) +{ + dlist_node *node; + TrackedIO *tio; + + Assert(ioq->has_reserved); + ioq->has_reserved = false; + + Assert(!dclist_is_empty(&ioq->idle)); + + node = dclist_pop_head_node(&ioq->idle); + tio = dclist_container(TrackedIO, node, node); + + tio->iow = *iow; + + dclist_push_tail(&ioq->in_progress, &tio->node); + + ioq->unsubmitted++; + + /* + * XXX: Should have some smarter logic here. We don't want to wait too + * long to submit, that'll mean we're more likely to block. But we also + * don't want to have the overhead of submitting every IO individually. + */ + if (ioq->unsubmitted >= 4) + { + pgaio_submit_staged(); + ioq->unsubmitted = 0; + } +} + +void +io_queue_wait_all(IOQueue *ioq) +{ + /* submit all pending IO before waiting */ + pgaio_submit_staged(); + + while (!dclist_is_empty(&ioq->in_progress)) + { + /* wait for the last IO to minimize unnecessary wakeups */ + dlist_node *node = dclist_tail_node(&ioq->in_progress); + TrackedIO *tio = dclist_container(TrackedIO, node, node); + + if (!pgaio_wref_check_done(&tio->iow)) + { + ereport(DEBUG3, + errmsg("io_queue_wait_all for io:%d", + pgaio_wref_get_id(&tio->iow)), + errhidestmt(true), + errhidecontext(true)); + + pgaio_wref_wait(&tio->iow); + } + + dclist_delete_from(&ioq->in_progress, &tio->node); + dclist_push_head(&ioq->idle, &tio->node); + } +} + +bool +io_queue_is_empty(IOQueue *ioq) +{ + return dclist_is_empty(&ioq->in_progress); +} + +void +io_queue_free(IOQueue *ioq) +{ + io_queue_wait_all(ioq); + + pfree(ioq); +} diff --git a/src/backend/storage/aio/meson.build b/src/backend/storage/aio/meson.build index da6df2d3654..270c4a64428 100644 --- a/src/backend/storage/aio/meson.build +++ b/src/backend/storage/aio/meson.build @@ -7,6 +7,7 @@ backend_sources += files( 'aio_init.c', 'aio_io.c', 'aio_target.c', + 'io_queue.c', 'method_io_uring.c', 'method_sync.c', 'method_worker.c', diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 3a67ee01b46..0c6ddadc51d 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1196,6 +1196,7 @@ IOContext IOFuncSelector IOObject IOOp +IOQueue IO_STATUS_BLOCK IPCompareMethod ITEM @@ -3022,6 +3023,7 @@ TocEntry TokenAuxData TokenizedAuthLine TrackItem +TrackedIO TransApplyAction TransInvalidationInfo TransState -- 2.48.1.76.g4e746b1a31.dirty --xevce4sdbnyxplun Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v2.15-0013-bufmgr-use-AIO-in-checkpointer-bgwriter.patch" ^ permalink raw reply [nested|flat] 10+ messages in thread
end of thread, other threads:[~2025-03-18 18:40 UTC | newest] Thread overview: 10+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-11-29 04:29 [PATCH v32 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v30 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v26 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v28 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v31 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v33 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v25 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v27 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2020-11-29 04:29 [PATCH v24 10/11] Preserve pg_stat_file() isdir.. Justin Pryzby <[email protected]> 2025-03-18 18:40 [PATCH v2.15 12/18] aio: Add IO queue helper Andres Freund <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox