Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

External file access extension

Allow access to "external files" from PostgreSQL server file systems.

This extension adds the same functionalities given by the Oracle's BFILE data type that stores unstructured binary data in flat files outside the database. A BFILE column stores a file locator that points to an external file containing the data: (DIRECTORY, FILENAME). Here the data type is called EFILE.

The extension access to external files using secure call to the server side lo_* functions and not by directly reading/writing to files.

Installation requirements

PostgreSQL 9.1 or better are required. User with PostgreSQL superuser role for creating extension.

Installation

external_file has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS".

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package).

Get/Unpack the source code in a fresh directory Then the software installation should be as simple as

$ make (In these version do nothing)
$ make install

To install the extension in a database, connect as superuser and

CREATE EXTENSION external_file;

By default all objects of the extension are created in the external_file schema. If you want to change the schema name you must edit the external_file.control file. Note that this schema must not be writable by normal user to not allow bypassing of the search path set with the security definer.

When using schema with extension, it's better to include this schema in the default search path. For example:

ALTER DATABASE <mydb> SET search_path="$user",public,external_file;

Also you can restrict USAGE grant on external_file schema to specific user and change the default search path at user level too.

GRANT USAGE ON SCHEMA external_file TO <username>;

Please refer to the PostgreSQL documentation for more information.

Usage

External file are accessed using two values, an alias for the path of the directory where the file is, and the file name.

So, first, alias must be defined for the path. This definition is performed using the "directories" table. For security reason, only superuser can insert, update, delete directory definition. It's possible, with GRANT command, to change this but it's NOT recommended.

Example:

INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');

ATTENTION:

  • the directory path must use the terminal file system separator!
  • the system user running PostgreSQL server (generally postgres) must have the system rights to read and/or write files. See pg_read_server_files and pg_write_server_files privileges introduced in PostgreSQL 11.
  • the filename don't include any / or \ character for security reason

Second, rights for user and/or role are defined using the "directory_access" table.

Example:

INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);

Now standard user can use external files.

Example:

-- Store a new external file blahblah.txt into the directory
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
ls -la /tmp/blahblah.txt -rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-- Create a table that will use external files
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
-- Insert a row to access the external file called blahblah.txt
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
-- Assuming user has right to read, and the file exists
SELECT id, readefile(the_file) FROM efile_test;
-- Make a physical copy of the external file assuming user has right to read AND write
SELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));
INSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);
-- or the equivalent using efilename()
INSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));
ls /tmp/*blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile ----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
2 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
(2 lines)

Function reference

  • efilename(directory in name, filename in varchar(256)) returns efile

    Returns an EFILE data type that is referencing the external file on the server filesystem. Returns NULL on null imput.

  • readEfile(e_file in efile) returns bytea

    copy the external file into a bytea. Error will be generated if something wrong.

  • writeEfile(buffer in bytea, e_file in efile) returns void

    copy a bytea into a external file. Error will be generated if something wrong.

  • copyEfile(src in efile, dest in efile) returns void

    duplicate file defined by src into file dest Error will be generated if something wrong.

  • getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text

    giving an efile and booleans, one for read and one for write need, return the full path for the file, otherwise an error is generated useful to check if session user has access to this external file

Authors

  • Dominique Legendre
  • Gilles Darold

License

external_file is free software distributed under the PostgreSQL Licence.

  • Copyright (c) 2012-2018 Brgm - All rights reserved.
  • Copyright (c) 2022 MigOps Inc - All rights reserved.

See LICENSE file.

About

Allow access to "external files" from PostgreSQL server file systems.

Resources

Stars

41 stars

Watchers

10 watching

Forks

Releases

Packages

Contributors

Languages