{"id":37782583,"url":"https://github.com/pgspider/influxdb_fdw","last_synced_at":"2026-01-16T15:09:24.109Z","repository":{"id":34584574,"uuid":"140357982","full_name":"pgspider/influxdb_fdw","owner":"pgspider","description":"InfluxDB Foreign Data Wrapper for PostgreSQL.","archived":false,"fork":false,"pushed_at":"2024-12-24T07:37:36.000Z","size":4793,"stargazers_count":58,"open_issues_count":7,"forks_count":15,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-12-24T08:32:22.019Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgspider.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-10T00:52:41.000Z","updated_at":"2024-12-24T07:37:44.000Z","dependencies_parsed_at":"2024-01-09T08:29:05.153Z","dependency_job_id":"ff613d95-360f-4724-96c6-9bd488a030ed","html_url":"https://github.com/pgspider/influxdb_fdw","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/pgspider/influxdb_fdw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgspider%2Finfluxdb_fdw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgspider%2Finfluxdb_fdw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgspider%2Finfluxdb_fdw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgspider%2Finfluxdb_fdw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgspider","download_url":"https://codeload.github.com/pgspider/influxdb_fdw/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgspider%2Finfluxdb_fdw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-16T15:09:23.392Z","updated_at":"2026-01-16T15:09:24.097Z","avatar_url":"https://github.com/pgspider.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"InfluxDB Foreign Data Wrapper for PostgreSQL\n============================================\n\nThis is a foreign data wrapper (FDW) to connect [PostgreSQL](https://www.postgresql.org/)\nto [InfluxDB](https://www.influxdata.com) database file. This FDW works with PostgreSQL 13, 14, 15, 16, 17 and confirmed with\n- InfluxDB 1.8: with either [influxdb1-go](#install-influxdb-go-client-library) client or [influxdb-cxx](#install-influxdb_cxx-client-library) client.\n- InfluxDB 2.7: with [influxdb-cxx](#install-influxdb_cxx-client-library) client via InfluxDB v1 compatibility API.\n\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/2/29/Postgresql_elephant.svg\" align=\"center\" height=\"100\" alt=\"PostgreSQL\"/\u003e\t+\t\u003cimg src=\"https://assets.zabbix.com/img/brands/influxdb.svg\" align=\"center\" height=\"100\" alt=\"InfluxDB\"/\u003e\n\nContents\n--------\n\n1. [Features](#features)\n2. [Supported platforms](#supported-platforms)\n3. [Installation](#installation)\n4. [Usage](#usage)\n5. [Functions](#functions)\n6. [Identifier case handling](#identifier-case-handling)\n7. [Generated columns](#generated-columns)\n8. [Character set handling](#character-set-handling)\n9. [Examples](#examples)\n10. [Limitations](#limitations)\n11. [Contributing](#contributing)\n12. [Useful links](#useful-links)\n13. [License](#license)\n\nFeatures\n--------\n### Common features\n\n- InfluxDB FDW supports `INSERT`, `DELETE` statements.\n  - `time` and `time_text` column can used for `INSERT`, `DELETE` statements.\n  - `time` column can express timestamp with precision down to microseconds.\n  - `time_text` column can express timestamp with precision down to nanoseconds.\n- InfluxDB FDW supports bulk `INSERT` by using `batch_size` option (with PostgreSQL 14+).\n\n#### `GROUP BY` time intervals and `fill()`\n\nSupport `GROUP BY` `times()` `fill()` syntax for InfluxDB.\nThe `fill()` is supported by two stub function:\n- `influx_fill_numeric()`: use with numeric parameter for example: `100`, `100.1111`\n- `influx_fill_option()`: use with specified option such as: `none`, `null`, `linear`, `previous`.\n\nThe `influx_fill_numeric()` and `influx_fill_option()` is embeded as last parameter of `time()` function. The table below illustrates the usage:\n\n| PostgreSQL syntax | Influxdb Syntax |\n|-------------------|-----------------|\n|influx_time(time, interval '2h')|time(2h)|\n|influx_time(time, interval '2h', interval '1h')|time(2h, 1h)|\n|influx_time(time, interval '2h', influx_fill_numeric(100))|time(2h) fill(100)|\n|influx_time(time, interval '2h', influx_fill_option('linear'))|time(2h) fill(linear)|\n|influx_time(time, interval '2h', interval '1h', influx_fill_numeric(100))|time(2h, 1h) fill(100)|\n|influx_time(time, interval '2h', interval '1h', influx_fill_option('linear'))|time(2h,1h) fill(linear)|\n\n#### Schemaless feature\n- The feature enables user to utilize schema-less feature of InfluxDB, enabled by setting special options.\n- For example, without schemaless feature if a tag-key or field-key is added to InfluxDB measurement, user have to create corresponding foreign table in PostgreSQL. This feature eliminates this re-creation of foreign table.\n\nColumns of foreign table in schemaless mode\n- The columns are fixed with names and types as below:\n  \u003cpre\u003e\n    (time timestamp with time zone, tags jsonb, fields jsonb)\n  \u003c/pre\u003e\n- The tag and/or field keys of InfluxDB are represented by key-value column in PostgreSQL's `jsonb` type.\n- The columns are created with `tags` or `fields` foreign column options:\n  - tags `true` indicates this column as containing values of tags in InfluxDB measurement.\n  - fields `true` indicates this column as containing values of fields in InfluxDB measurement.\n- Creation of foreign table in schemaless mode, for example:\n  \n  ```sql\n  -- Create foreign table\n\tCREATE FOREIGN TABLE sc1(\n\t  time timestamp with time zone,\n          tags jsonb OPTIONS(tags 'true'),\n          fields jsonb OPTIONS (fields 'true')\n\t)\n\tSERVER influxdb_svr\n\tOPTIONS (\n\t  table 'sc1',\n          tags 'device_id',\n          schemaless 'true'\n\t);\n  -- import foreign schema\n\tIMPORT FOREIGN SCHEMA public\n\tFROM SERVER influxdb_svr\n\tINTO public\n\tOPTIONS (\n          schemaless 'true'\n        );\n  ```\nQuerying foreign tables:\n- Initialize data in InfluxDB.\n  \u003cpre\u003e\n  sc1,device_id=dev1 sig1=1i,sig2=\"a\",sig3=1.1,sig4=true 0\n  sc1,device_id=dev2 sig1=2i,sig2=\"b\",sig3=1.2,sig4=false 0\n  sc1,device_id=dev3 sig1=3i,sig2=\"c\",sig3=1.3,sig4=false 0\n  sc1,device_id=dev1 sig1=4i,sig2=\"d\",sig3=2.4,sig4=true 1\n  sc1,device_id=dev2 sig1=5i,sig2=\"e\",sig3=2.5,sig4=false 1\n  sc1,device_id=dev3 sig1=6i,sig2=\"f\",sig3=2.6,sig4=false 1\n  sc1,device_id=dev1 sig1=7i,sig2=\"g\",sig3=3.7,sig4=true 2\n  sc1,device_id=dev2 sig1=8i,sig2=\"h\",sig3=3.8,sig4=false 2\n  sc1,device_id=dev3 sig1=9i,sig2=\"i\",sig3=3.9,sig4=false 2\n  \u003c/pre\u003e\n\n- Get data through schemaless foreign table:\n  ```sql\n  EXPLAIN VERBOSE\n  SELECT * FROM sc1;\n                              QUERY PLAN\n  --------------------------------------------------------------------\n  Foreign Scan on public.sc1  (cost=10.00..853.00 rows=853 width=72)\n    Output: \"time\", tags, fields\n    InfluxDB query: SELECT * FROM \"sc1\"\n  (3 rows)\n\n  SELECT * FROM sc1;\n            time          |         tags          |                           fields\n  ------------------------+-----------------------+------------------------------------------------------------\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev1\"} | {\"sig1\": \"1\", \"sig2\": \"a\", \"sig3\": \"1.1\", \"sig4\": \"true\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev2\"} | {\"sig1\": \"2\", \"sig2\": \"b\", \"sig3\": \"1.2\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev3\"} | {\"sig1\": \"3\", \"sig2\": \"c\", \"sig3\": \"1.3\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev1\"} | {\"sig1\": \"4\", \"sig2\": \"d\", \"sig3\": \"2.4\", \"sig4\": \"true\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev2\"} | {\"sig1\": \"5\", \"sig2\": \"e\", \"sig3\": \"2.5\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev3\"} | {\"sig1\": \"6\", \"sig2\": \"f\", \"sig3\": \"2.6\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev1\"} | {\"sig1\": \"7\", \"sig2\": \"g\", \"sig3\": \"3.7\", \"sig4\": \"true\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev2\"} | {\"sig1\": \"8\", \"sig2\": \"h\", \"sig3\": \"3.8\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev3\"} | {\"sig1\": \"9\", \"sig2\": \"i\", \"sig3\": \"3.9\", \"sig4\": \"false\"}\n  (9 rows)\n  ```\n\nFetch values in jsonb expression:\n- Using `-\u003e\u003e` `jsonb` arrow operator to fetch actual remote InfluxDB tag or fields keys from foreign schemaless columns.\n  User may cast type of the jsonb expression to get corresponding data representation.\n- For example, `fields-\u003e\u003e'sig1'` expression of fetch value `sig1` is actual field key `sig1` in remote data source InfluxDB.\n- The `jsonb` expression can be pushed down in `WHERE`, `GROUP BY`, `ORDER BY` and aggregation.\n\nFor examples:\n- Fetch all column based on all actual columns:\n  ```sql\n  EXPLAIN VERBOSE\n  SELECT time,tags-\u003e\u003e'device_id' device_id,(fields-\u003e\u003e'sig1')::bigint sig1,fields-\u003e\u003e'sig2' sig2,(fields-\u003e\u003e'sig3')::double precision sig3,(fields-\u003e\u003e'sig4')::boolean sig4 FROM sc1;\n                                                                                              QUERY PLAN                                                                                              \n  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n  Foreign Scan on public.sc1  (cost=10.00..876.46 rows=853 width=89)\n    Output: \"time\", (tags -\u003e\u003e 'device_id'::text), ((fields -\u003e\u003e 'sig1'::text))::bigint, (fields -\u003e\u003e 'sig2'::text), ((fields -\u003e\u003e 'sig3'::text))::double precision, ((fields -\u003e\u003e 'sig4'::text))::boolean\n    InfluxDB query: SELECT \"device_id\", \"sig1\", \"sig2\", \"sig3\", \"sig4\" FROM \"sc1\"\n  (3 rows)\n\n  SELECT time,tags-\u003e\u003e'device_id' device_id,(fields-\u003e\u003e'sig1')::bigint sig1,fields-\u003e\u003e'sig2' sig2,(fields-\u003e\u003e'sig3')::double precision sig3,(fields-\u003e\u003e'sig4')::boolean sig4 FROM sc1;\n            time          | device_id | sig1 | sig2 | sig3 | sig4 \n  ------------------------+-----------+------+------+------+------\n  1970-01-01 09:00:00+09 | dev1      |    1 | a    |  1.1 | t\n  1970-01-01 09:00:00+09 | dev2      |    2 | b    |  1.2 | f\n  1970-01-01 09:00:00+09 | dev3      |    3 | c    |  1.3 | f\n  1970-01-01 09:00:00+09 | dev1      |    4 | d    |  2.4 | t\n  1970-01-01 09:00:00+09 | dev2      |    5 | e    |  2.5 | f\n  1970-01-01 09:00:00+09 | dev3      |    6 | f    |  2.6 | f\n  1970-01-01 09:00:00+09 | dev1      |    7 | g    |  3.7 | t\n  1970-01-01 09:00:00+09 | dev2      |    8 | h    |  3.8 | f\n  1970-01-01 09:00:00+09 | dev3      |    9 | i    |  3.9 | f\n  (9 rows)\n  ```\n\n- `jsonb` expression is pushed down in `WHERE`.\n  ```sql\n  EXPLAIN VERBOSE\n  SELECT * FROM sc1 WHERE (fields-\u003e\u003e'sig3')::double precision \u003e 2;\n                              QUERY PLAN\n  --------------------------------------------------------------------\n  Foreign Scan on public.sc1  (cost=10.00..284.00 rows=284 width=72)\n    Output: \"time\", tags, fields\n    InfluxDB query: SELECT * FROM \"sc1\" WHERE ((\"sig3\" \u003e 2))\n  (3 rows)\n\n  SELECT * FROM sc1 WHERE (fields-\u003e\u003e'sig3')::double precision \u003e 2;\n            time          |         tags          |                           fields\n  ------------------------+-----------------------+------------------------------------------------------------\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev1\"} | {\"sig1\": \"4\", \"sig2\": \"d\", \"sig3\": \"2.4\", \"sig4\": \"true\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev2\"} | {\"sig1\": \"5\", \"sig2\": \"e\", \"sig3\": \"2.5\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev3\"} | {\"sig1\": \"6\", \"sig2\": \"f\", \"sig3\": \"2.6\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev1\"} | {\"sig1\": \"7\", \"sig2\": \"g\", \"sig3\": \"3.7\", \"sig4\": \"true\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev2\"} | {\"sig1\": \"8\", \"sig2\": \"h\", \"sig3\": \"3.8\", \"sig4\": \"false\"}\n  1970-01-01 09:00:00+09 | {\"device_id\": \"dev3\"} | {\"sig1\": \"9\", \"sig2\": \"i\", \"sig3\": \"3.9\", \"sig4\": \"false\"}\n  (6 rows)\n  ```\n\n- `jsonb` expression is pushed down in aggregate `sum` (remote) + tag + `group by`\n  ```sql\n\n  EXPLAIN VERBOSE\n  SELECT sum((fields-\u003e\u003e'sig1')::bigint),tags-\u003e\u003e'device_id' device_id FROM sc1 GROUP BY tags-\u003e\u003e'device_id';\n                                        QUERY PLAN\n  --------------------------------------------------------------------------------------\n  Foreign Scan  (cost=1.00..1.00 rows=1 width=64)\n    Output: (sum(((fields -\u003e\u003e 'sig1'::text))::bigint)), ((tags -\u003e\u003e 'device_id'::text))\n    InfluxDB query: SELECT sum(\"sig1\") FROM \"sc1\" GROUP BY (\"device_id\")\n  (3 rows)\n\n  SELECT sum((fields-\u003e\u003e'sig1')::bigint),tags-\u003e\u003e'device_id' device_id FROM sc1 GROUP BY tags-\u003e\u003e'device_id';\n  sum | device_id\n  -----+-----------\n    12 | dev1\n    15 | dev2\n    18 | dev3\n  (3 rows)\n  ```\n\n### Pushdowning\n\n- `WHERE` clauses including `timestamp`, `interval` and `now()` functions.\n- Some of aggregate functions: `count`, `stddev`, `sum`, `max`, `min`.\n- `LIMIT...OFFSET` clauses when there is `LIMIT` clause only or both `LIMIT` and `OFFSET`.\n- `DISTINCT` argument for only `count` clause.\n- `ANY ARRAY`.\n\n### Notes about features\n\n#### The existence of `NULL` values depends on the target list in remote query in InfluxDB\n- If specific field keys are selected, InfluxDB does not return `NULL` values for any row that has `NULL` value.\n- In InfluxDB, `SELECT tag_keys` - selecting only tag keys does not return values, so some field keys are required to be selected.\nCurrent implementation of non-schemaless need arbitrary on field key added to remote select query. And this is a limitation of current `influxdb_fdw`, e.g. remote query: `SELECT tag_keys, field_key`.\nEven though the field key has `NULL` values, this InfluxDB query does not return `NULL` values.\n- If all field key is selected by `SELECT *` in remote query, `NULL` values are returned by InfluxDB.\n\nFor example:\n- Initialize data: 8 records are inserted.\n```sql\n  CREATE FOREIGN TABLE J2_TBL (\n    i integer,\n    k integer\n  ) SERVER influxdb_svr;\n\n  -- Insert data with some null values\n  INSERT INTO J2_TBL VALUES (1, -1);\n  INSERT INTO J2_TBL VALUES (2, 2);\n  INSERT INTO J2_TBL VALUES (3, -3);\n  INSERT INTO J2_TBL VALUES (2, 4);\n  INSERT INTO J2_TBL VALUES (5, -5);\n  INSERT INTO J2_TBL VALUES (5, -5);\n  INSERT INTO J2_TBL VALUES (0, NULL);\n  INSERT INTO J2_TBL VALUES (NULL, 0);\n```\n- Query in InfluxDB server by selecting specific field keys: 7 records are returned without null value.\n```sql\n  SELECT k FROM j2_tbl;\n  name: j2_tbl\n  time k\n  ---- -\n  1    -1\n  2    2\n  3    -3\n  4    4\n  5    -5\n  6    -5\n  10   0\n```\n- Query in InfluxDB server by selecting all field key: 8 records are returned with null value.\n```sql\n  SELECT * FROM j2_tbl;\n  name: j2_tbl\n  time i k\n  ---- - -\n  1    1 -1\n  2    2 2\n  3    3 -3\n  4    2 4\n  5    5 -5\n  6    5 -5\n  7    0\n  10     0\n```\n\n#### The targets list contains both functions and `fields` schemaless jsonb column\n- If the targets list contains both functions and `fields` schemaless `jsonb` column, the function is not pushed down.\n- For examples, if the target list contains:\n  - `fields, fields-\u003e\u003e'c2', sqrt((fields-\u003e\u003e'c1')::int)`: function `sqrt()` is not pushed down.\n  - `fields, sqrt((fields-\u003e\u003e'c1')::int)`: function `sqrt()` is not pushed down.\n  - `fields-\u003e\u003e'c2', sqrt((fields-\u003e\u003e'c1')::int)`: there is no fields jsonb column, so function `sqrt()` is pushed down.\n\nAlso see [Limitations](#limitations).\n\n### Time operator support for both schemaless and non-schemaless\n- (1) For comparison between time key column with time constant, time param, `now()` function, time expression with `now()` function, InfluxDB FDW pushes down the following operators: `=`, `\u003c`, `\u003e`, `\u003e=`, `\u003c=`.\n- (2) For comparsion between tags/fields column with tags/fields, time constant, time param, InfluxDB FDW pushes down the operator `=`, `!=`, `\u003c\u003e`.\n- (3) For comparison with time key column, InfluxDB FDW does not push down `!=` and `\u003c\u003e`.\n- (4) For comparison between `interval` and `interval`, InfluxDB FDW does not pushdown.\n- (5) For comparison with time function which is not `now()`, InfluxDB FDW does not pushdown\n- (6) For comparison between time key and time column, InfluxDB FDW does not pushdown the folowing operators `\u003c`, `\u003e`, `\u003c=`, `\u003e=`, `=`.\n- (7) For comparison between tags/fields with tags/fields, time constant, time param, InfluxDB FDW does not pushdown the operators `\u003c`, `\u003e`, `\u003c=`, `\u003e=`.\n- (8) For comparison between time expression `time +/- interval` with `time` (not time key), InfluxDB FDW does not pushdown.\n- (9) For comparison between time expression `time column +/- interval`, `param +/- interval` with time key, InfluxDB FDW does not pushdown\n\nFor example:\n- Create a foreign table with all types of time column that InfluxDB FDW supports now. The examples below show examples for each points in non-schemaless, please refer to the test for more test cases of both schemaless and non-schemaless.\n\n```sql\nCREATE FOREIGN TABLE tmp_time (\ntime timestamp,\nc1 time,\nc2 timestamp,\nc3 timestamp with time zone,\nagvState character varying NULL COLLATE pg_catalog.\"default\",\nvalue numeric NULL\n) SERVER server1 OPTIONS (table 'tmp_time');\n\nINSERT INTO tmp_time (time, c1, agvState, value) VALUES ('1900-01-01 01:01:01', '01:02:03', 'state 1', 0.1);\nINSERT INTO tmp_time (time, c1, agvState, value) VALUES ('2100-01-01 01:01:01', '04:05:06', 'state 2', 0.2);\nINSERT INTO tmp_time (time, c1, agvState, value) VALUES ('1990-01-01 01:01:01', '07:08:09', 'state 3', 0.3);\nINSERT INTO tmp_time (time, c2) VALUES ('2020-12-27 03:02:56.634467', '1950-02-02 02:02:02');\nINSERT INTO tmp_time (time, c3, agvState, value) VALUES ('2021-12-27 03:02:56.668301', '1800-02-02 02:02:02+9', 'state 5', 0.5);\nINSERT INTO tmp_time (time, c1, c2, c3, agvState, value) VALUES ('2022-05-06 07:08:09', '07:08:09', '2022-05-06 07:08:09', '2022-05-06 07:08:09+9', 'state 6', 0.6);\nINSERT INTO tmp_time (time, c1, c2, c3, agvState, value) VALUES ('2023-05-06 07:08:09', '07:08:10', '2023-05-06 07:08:09', '2023-05-06 07:08:09+9', 'state 7', 0.7);\nINSERT INTO tmp_time (time, c1, c2, c3, c4, c5, agvState, value) VALUES ('2023-05-06 07:08:09', '07:08:10', '2023-05-06 07:08:09', '2023-05-06 07:08:09+9', '2023-05-06 08:08:09', '2023-05-06 08:08:09+9', 'state 8', 0.8);\nINSERT INTO tmp_time (time, c1, c2, c3, c4, c5, agvState, value) VALUES ('2025-05-06 07:08:09', '07:08:10', '2025-05-06 07:08:09', '2025-05-06 07:08:09+9', '2025-05-06 08:08:09', '2025-05-06 08:08:09+9', 'state 9', 0.9);\n\n```\n- Example for point (1):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE time \u003e '2022-05-06 07:08:09';\n                                                      QUERY PLAN                                                       \n-----------------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..227.00 rows=227 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\" WHERE ((time \u003e '2022-05-06 07:08:09'))\n(3 rows)\n\nSELECT * FROM tmp_time WHERE time \u003e '2022-05-06 07:08:09';\n        time         |    c1    |         c2          |           c3           | agvstate | value \n---------------------+----------+---------------------+------------------------+----------+-------\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | state 7  |   0.7\n 2100-01-01 01:01:01 | 04:05:06 |                     |                        | state 2  |   0.2\n(2 rows)\n```\n- Example for point (2):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE c2 \u003e '1950-02-02 02:02:02';\n                                   QUERY PLAN                                   \n--------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..227.00 rows=227 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   Filter: (tmp_time.c2 \u003e '1950-02-02 02:02:02'::timestamp without time zone)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE c2 \u003e '1950-02-02 02:02:02';\n        time         |    c1    |         c2          |           c3           | agvstate | value \n---------------------+----------+---------------------+------------------------+----------+-------\n 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 | state 6  |   0.6\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | state 7  |   0.7\n(2 rows)\n\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE c2 = '2022-05-06 07:08:09';\n                                                      QUERY PLAN                                                       \n-----------------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..3.00 rows=3 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\" WHERE ((\"c2\" = '2022-05-06 07:08:09'))\n(3 rows)\n\nSELECT * FROM tmp_time WHERE c2 = '2022-05-06 07:08:09';\n        time         |    c1    |         c2          |           c3           | agvstate | value \n---------------------+----------+---------------------+------------------------+----------+-------\n 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 | state 6  |   0.6\n(1 row)\n```\n- Example for point (3):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE time != '2022-05-06 07:08:09';\n                                    QUERY PLAN                                     \n-----------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..679.00 rows=679 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   Filter: (tmp_time.\"time\" \u003c\u003e '2022-05-06 07:08:09'::timestamp without time zone)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE time != '2022-05-06 07:08:09';\n            time            |    c1    |         c2          |              c3              | agvstate | value \n----------------------------+----------+---------------------+------------------------------+----------+-------\n 1900-01-01 01:01:01        | 01:02:03 |                     |                              | state 1  |   0.1\n 1990-01-01 01:01:01        | 07:08:09 |                     |                              | state 3  |   0.3\n 2020-12-27 03:02:56.634467 |          | 1950-02-02 02:02:02 |                              |          |      \n 2021-12-27 03:02:56.668301 |          |                     | 1800-02-02 02:21:01+09:18:59 | state 5  |   0.5\n 2023-05-06 07:08:09        | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09       | state 7  |   0.7\n 2100-01-01 01:01:01        | 04:05:06 |                     |                              | state 2  |   0.2\n(6 rows)\n```\n- Example for point (4):\n```sql\n-- Does not push down time subtraction time - time vs interval\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE time - c2 \u003c= interval '1d';\n                                   QUERY PLAN                                   \n--------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..227.00 rows=227 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   Filter: ((tmp_time.\"time\" - tmp_time.c2) \u003c= '@ 1 day'::interval)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE time - c2 \u003c= interval '1d';\n        time         |    c1    |         c2          |           c3           | agvstate | value \n---------------------+----------+---------------------+------------------------+----------+-------\n 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 | state 6  |   0.6\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | state 7  |   0.7\n(2 rows)\n\n-- Does not push down nested time subtraction\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE (time - c2) - (c1 - c1) \u003e interval '-1d';\n                                              QUERY PLAN                                               \n-------------------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..227.00 rows=227 width=96)\n   Output: \"time\", c1, c2, c3, agvstate, value\n   Filter: (((tmp_time.\"time\" - tmp_time.c2) - (tmp_time.c1 - tmp_time.c1)) \u003e '@ 1 day ago'::interval)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE (time - c2) - (c1 - c1) \u003e interval '-1d';\n        time         |    c1    |         c2          |           c3           | agvstate | value \n---------------------+----------+---------------------+------------------------+----------+-------\n 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 | state 6  |   0.6\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | state 7  |   0.7\n(2 rows)\n\n```\n- Example for point (5):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE influx_time(time, interval '3m') - interval '3m' \u003c time;\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..201.00 rows=201 width=112)\n   Output: \"time\", c1, c2, c3, c4, c5, agvstate, value\n   Filter: ((influx_time(tmp_time.\"time\", '@ 3 mins'::interval) - '@ 3 mins'::interval) \u003c tmp_time.\"time\")\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"c4\", \"c5\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE influx_time(time, interval '3m') - interval '3m' \u003c time;\nERROR:  stub influx_time(timestamp with time zone, interval) is called\nCONTEXT:  PL/pgSQL function influx_time(timestamp with time zone,interval) line 3 at RAISE\n```\n- Example for point (6):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE time = c2;\n                                         QUERY PLAN                                         \n--------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..3.00 rows=3 width=112)\n   Output: \"time\", c1, c2, c3, c4, c5, agvstate, value\n   Filter: (tmp_time.\"time\" = tmp_time.c2)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"c4\", \"c5\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE time = c2;\n        time         |    c1    |         c2          |           c3           |         c4          |           c5           | agvstate | value \n---------------------+----------+---------------------+------------------------+---------------------+------------------------+----------+-------\n 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 |                     |                        | state 6  |   0.6\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | 2023-05-06 08:08:09 | 2023-05-06 08:08:09+09 | state 8  |   0.8\n 2025-05-06 07:08:09 | 07:08:10 | 2025-05-06 07:08:09 | 2025-05-06 07:08:09+09 | 2025-05-06 08:08:09 | 2025-05-06 08:08:09+09 | state 9  |   0.9\n(3 rows)\n```\n- Example for point (7):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE c2 \u003c c4;\n                                         QUERY PLAN                                         \n--------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..201.00 rows=201 width=112)\n   Output: \"time\", c1, c2, c3, c4, c5, agvstate, value\n   Filter: (tmp_time.c2 \u003c tmp_time.c4)\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"c4\", \"c5\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\n--Testcase 471:\nSELECT * FROM tmp_time WHERE c2 \u003c c4;\n        time         |    c1    |         c2          |           c3           |         c4          |           c5           | agvstate | value \n---------------------+----------+---------------------+------------------------+---------------------+------------------------+----------+-------\n 2023-05-06 07:08:09 | 07:08:10 | 2023-05-06 07:08:09 | 2023-05-06 07:08:09+09 | 2023-05-06 08:08:09 | 2023-05-06 08:08:09+09 | state 8  |   0.8\n 2025-05-06 07:08:09 | 07:08:10 | 2025-05-06 07:08:09 | 2025-05-06 07:08:09+09 | 2025-05-06 08:08:09 | 2025-05-06 08:08:09+09 | state 9  |   0.9\n(2 rows)\n\n```\n- Example for point (8):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE (time + interval '1d') \u003e now() + interval '-1d';\n                                         QUERY PLAN                                         \n--------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..201.00 rows=201 width=112)\n   Output: \"time\", c1, c2, c3, c4, c5, agvstate, value\n   Filter: ((tmp_time.\"time\" + '@ 1 day'::interval) \u003e (now() + '@ 1 day ago'::interval))\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"c4\", \"c5\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE (time + interval '1d') \u003e now() + interval '-1d';\n        time         |    c1    |         c2          |           c3           |         c4          |           c5           | agvstate | value \n---------------------+----------+---------------------+------------------------+---------------------+------------------------+----------+-------\n 2025-05-06 07:08:09 | 07:08:10 | 2025-05-06 07:08:09 | 2025-05-06 07:08:09+09 | 2025-05-06 08:08:09 | 2025-05-06 08:08:09+09 | state 9  |   0.9\n 2100-01-01 01:01:01 | 04:05:06 |                     |                        |                     |                        | state 2  |   0.2\n(2 rows)\n```\n- Example for point (9):\n```sql\nEXPLAIN VERBOSE\nSELECT * FROM tmp_time WHERE time = c2 + interval '25896 days 01:00:54.634467';\n                                          QUERY PLAN                                          \n----------------------------------------------------------------------------------------------\n Foreign Scan on public.tmp_time  (cost=10.00..3.00 rows=3 width=112)\n   Output: \"time\", c1, c2, c3, c4, c5, agvstate, value\n   Filter: (tmp_time.\"time\" = (tmp_time.c2 + '@ 25896 days 1 hour 54.634467 secs'::interval))\n   InfluxDB query: SELECT \"c1\", \"c2\", \"c3\", \"c4\", \"c5\", \"agvstate\", \"value\" FROM \"tmp_time\"\n(4 rows)\n\nSELECT * FROM tmp_time WHERE time = c2 + interval '25896 days 01:00:54.634467';\n            time            | c1 |         c2          | c3 | c4 | c5 | agvstate | value \n----------------------------+----+---------------------+----+----+----+----------+-------\n 2020-12-27 03:02:56.634467 |    | 1950-02-02 02:02:02 |    |    |    |          |      \n(1 row)\n```\n#### Pattern Matching\nInfluxDB FDW supports pattern matching by using LIKE and Regular Expression (Regex) operator in WHERE clause. \u003cbr\u003e\nThe following operators are used: \u003cbr\u003e\n(1) `LIKE` or `~~`: Check if a value matches a LIKE pattern (case sensitive) \u003cbr\u003e\n(2) `NOT LIKE` or `!~~`: Check if a value does not match a LIKE pattern (case sensitive) \u003cbr\u003e\n(3) `ILIKE` or `~~*`: Check if a value matches a LIKE pattern (case insensitive) \u003cbr\u003e\n(4) `NOT ILIKE` or `!~~*`: Check if a value does not match a LIKE pattern (case insensitive) \u003cbr\u003e\n(5) `~`: Check if a value matches a Regex pattern (case sensitive) \u003cbr\u003e\n(6) `!~`: Check if a value does not match a Regex pattern (case sensitive) \u003cbr\u003e\n(7) `~*`: Check if a value matches a Regex pattern (case insensitive) \u003cbr\u003e\n(8) `!~*`: Check if a value does not match a Regex pattern (case insensitive) \u003cbr\u003e\n\nFor example,\n\n(1) `LIKE` operator (case sensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor LIKE 'A%';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /^A(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor LIKE 'A%';\n             time              | device | line | sensor | value \n-------------------------------+--------+------+--------+-------\n 2024-10-18 14:44:24.297985+09 | D01    | L01  | A32    |     1\n 2024-10-18 14:44:24.319444+09 | D02    | L02  | A31    |     2\n 2024-10-18 14:44:24.325517+09 | D03    | L03  | Alarm  |     3\n(3 rows)\n\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor LIKE '_PS5A_PS2_';\n                                                           QUERY PLAN                                                           \n--------------------------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /^(.{1})PS5A(.{1})PS2(.{1})$/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor LIKE '_PS5A_PS2_';\n             time              | device | line |   sensor   | value \n-------------------------------+--------+------+------------+-------\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$ |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_ |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2% |     9\n(3 rows)\n\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor LIKE '\\_PS5A\\_PS2\\_';\n                                                   QUERY PLAN                                                    \n-----------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /^_PS5A_PS2_$/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor LIKE '\\_PS5A\\_PS2\\_';\n             time              | device | line |   sensor   | value \n-------------------------------+--------+------+------------+-------\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_ |     8\n(1 row)\n\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor ~~ 'A%';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /^A(.*)/))\n(3 rows)\n\n\nSELECT * FROM sensor_tbl WHERE sensor ~~ 'A%';\n             time              | device | line | sensor | value \n-------------------------------+--------+------+--------+-------\n 2024-10-18 14:44:24.297985+09 | D01    | L01  | A32    |     1\n 2024-10-18 14:44:24.319444+09 | D02    | L02  | A31    |     2\n 2024-10-18 14:44:24.325517+09 | D03    | L03  | Alarm  |     3\n(3 rows)\n```\n\n(2) `NOT LIKE` operator (case sensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor NOT LIKE 'A%';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" !~ /^A(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor NOT LIKE 'A%';\n             time              | device | line |     sensor      | value \n-------------------------------+--------+------+-----------------+-------\n 2024-10-18 14:44:24.331317+09 | D04    | L04  | PS5A_PS2        |     4\n 2024-10-18 14:44:24.336539+09 | D05    | L05  | ^PS5A_PS2       |     5\n 2024-10-18 14:44:24.341984+09 | D06    | L06  | PS5A_PS2$       |     6\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$      |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_      |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2%      |     9\n 2024-10-18 14:44:24.368482+09 | D10    | L10  | \\^$.|?aBc*+()[{ |    10\n(7 rows)\n\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor !~~ 'A%';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" !~ /^A(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor !~~ 'A%';\n             time              | device | line |     sensor      | value \n-------------------------------+--------+------+-----------------+-------\n 2024-10-18 14:44:24.331317+09 | D04    | L04  | PS5A_PS2        |     4\n 2024-10-18 14:44:24.336539+09 | D05    | L05  | ^PS5A_PS2       |     5\n 2024-10-18 14:44:24.341984+09 | D06    | L06  | PS5A_PS2$       |     6\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$      |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_      |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2%      |     9\n 2024-10-18 14:44:24.368482+09 | D10    | L10  | \\^$.|?aBc*+()[{ |    10\n(7 rows)\n```\n\n(3) `ILIKE` operator (case insensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor ILIKE 'a3%';\n                                                   QUERY PLAN                                                   \n----------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /(?i)^a3(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor ILIKE 'a3%';\n             time              | device | line | sensor | value \n-------------------------------+--------+------+--------+-------\n 2024-10-18 14:44:24.297985+09 | D01    | L01  | A32    |     1\n 2024-10-18 14:44:24.297985+09 | D11    | L11  | A32\\%  |    11\n 2024-10-18 14:44:24.319444+09 | D02    | L02  | A31    |     2\n(3 rows)\n```\n\n(4) `NOT ILIKE` operator (case insenstive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor NOT ILIKE 'a3%';\n                                                   QUERY PLAN                                                   \n----------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" !~ /(?i)^a3(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor NOT ILIKE 'a3%';\n             time              | device | line |     sensor      | value \n-------------------------------+--------+------+-----------------+-------\n 2024-10-18 14:44:24.297988+09 | D12    | L12  | \\%              |    12\n 2024-10-18 14:44:24.297998+09 | D13    | L13  | %               |    13\n 2024-10-18 14:44:24.325517+09 | D03    | L03  | Alarm           |     3\n 2024-10-18 14:44:24.331317+09 | D04    | L04  | PS5A_PS2        |     4\n 2024-10-18 14:44:24.336539+09 | D05    | L05  | ^PS5A_PS2       |     5\n 2024-10-18 14:44:24.341984+09 | D06    | L06  | PS5A_PS2$       |     6\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$      |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_      |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2%      |     9\n 2024-10-18 14:44:24.368482+09 | D10    | L10  | \\^$.|?aBc*+()[{ |    10\n(10 rows)\n```\n\n(5) `~` Regex match operator (case sensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor ~ '^A(.*)';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /^A(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor ~ '^A(.*)';\n             time              | device | line | sensor | value \n-------------------------------+--------+------+--------+-------\n 2024-10-18 14:44:24.297985+09 | D01    | L01  | A32    |     1\n 2024-10-18 14:44:24.297985+09 | D11    | L11  | A32\\%  |    11\n 2024-10-18 14:44:24.319444+09 | D02    | L02  | A31    |     2\n 2024-10-18 14:44:24.325517+09 | D03    | L03  | Alarm  |     3\n(4 rows)\n```\n\n(6) `!~` Regex not match operator (case sensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor !~ '^A(.*)';\n                                                QUERY PLAN                                                 \n-----------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" !~ /^A(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor !~ '^A(.*)';\n             time              | device | line |     sensor      | value \n-------------------------------+--------+------+-----------------+-------\n 2024-10-18 14:44:24.297988+09 | D12    | L12  | \\%              |    12\n 2024-10-18 14:44:24.297998+09 | D13    | L13  | %               |    13\n 2024-10-18 14:44:24.331317+09 | D04    | L04  | PS5A_PS2        |     4\n 2024-10-18 14:44:24.336539+09 | D05    | L05  | ^PS5A_PS2       |     5\n 2024-10-18 14:44:24.341984+09 | D06    | L06  | PS5A_PS2$       |     6\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$      |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_      |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2%      |     9\n 2024-10-18 14:44:24.368482+09 | D10    | L10  | \\^$.|?aBc*+()[{ |    10\n(9 rows)\n```\n\n(7) `~*` Regex match operator (case insensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor ~* '^a3(.*)';\n                                                   QUERY PLAN                                                   \n----------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" =~ /(?i)^a3(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor ~* '^a3(.*)';\n             time              | device | line | sensor | value \n-------------------------------+--------+------+--------+-------\n 2024-10-18 14:44:24.297985+09 | D01    | L01  | A32    |     1\n 2024-10-18 14:44:24.297985+09 | D11    | L11  | A32\\%  |    11\n 2024-10-18 14:44:24.319444+09 | D02    | L02  | A31    |     2\n(3 rows)\n```\n\n(8) `!~*` Regex not match operator (case insensitive)\n```sql\nEXPLAIN (VERBOSE, COSTS OFF)\nSELECT * FROM sensor_tbl WHERE sensor !~* '^a3(.*)';\n                                                   QUERY PLAN                                                   \n----------------------------------------------------------------------------------------------------------------\n Foreign Scan on public.sensor_tbl\n   Output: \"time\", device, line, sensor, value\n   InfluxDB query: SELECT \"device\", \"line\", \"sensor\", \"value\" FROM \"sensor\" WHERE ((\"sensor\" !~ /(?i)^a3(.*)/))\n(3 rows)\n\nSELECT * FROM sensor_tbl WHERE sensor !~* '^a3(.*)';\n             time              | device | line |     sensor      | value \n-------------------------------+--------+------+-----------------+-------\n 2024-10-18 14:44:24.297988+09 | D12    | L12  | \\%              |    12\n 2024-10-18 14:44:24.297998+09 | D13    | L13  | %               |    13\n 2024-10-18 14:44:24.325517+09 | D03    | L03  | Alarm           |     3\n 2024-10-18 14:44:24.331317+09 | D04    | L04  | PS5A_PS2        |     4\n 2024-10-18 14:44:24.336539+09 | D05    | L05  | ^PS5A_PS2       |     5\n 2024-10-18 14:44:24.341984+09 | D06    | L06  | PS5A_PS2$       |     6\n 2024-10-18 14:44:24.347979+09 | D07    | L07  | ^PS5A_PS2$      |     7\n 2024-10-18 14:44:24.353777+09 | D08    | L08  | _PS5A_PS2_      |     8\n 2024-10-18 14:44:24.361595+09 | D09    | L09  | %PS5A%PS2%      |     9\n 2024-10-18 14:44:24.368482+09 | D10    | L10  | \\^$.|?aBc*+()[{ |    10\n(10 rows)\n```\n\nSupported platforms\n-------------------\n\n`influxdb_fdw` was developed on Linux, and should run on any\nreasonably POSIX-compliant system.\n\n`influxdb_fdw` is designed to be compatible with PostgreSQL 13 ~ 17.\n\nInstallation\n------------\n### Prerequisites\n\n`Influxdb_fdw` supports 2 different client:\n- Go client\n- `Influxdb_cxx` client.\n\nThe installation for each kind of client is described as below.\n\n#### Install InfluxDB Go client library\n\nGo version should be 1.10.4 or later.\n```\ngo get github.com/influxdata/influxdb1-client/v2\n```\nTo use Go client, use GO_CLIENT=1 flag when compile the source code\n\n#### Install `Influxdb_cxx` client library\n\nGet source code from [`influxdb-cxx`](https://github.com/pgspider/influxdb-cxx) github repository and install as manual:\n```\ngit clone https://github.com/pgspider/influxdb-cxx\ncd influxdb-cxx\ncmake .. -DINFLUXCXX_WITH_BOOST=OFF -DINFLUXCXX_TESTING=OFF\nsudo make install\n```\nUpdate `LD_LIBRARY_PATH` follow the installation folder of `Influxdb_cxx` client\n\nTo use `Influxdb_cxx`, use `CXX_CLIENT=1` flag when compile the source code. It is required to use `gcc` version 7 to build `influxdb_fdw` with `influxdb_cxx` client.\n\n### Source installation\nAdd a directory of `pg_config` to PATH and build and install `influxdb_fdw`.\nIf you want to build `influxdb_fdw` in a source tree of PostgreSQL instead, don't use `USE_PGXS=1`.\n\n#### Using Go client\n```sh\nmake USE_PGXS=1 with_llvm=no GO_CLIENT=1\nmake install USE_PGXS=1 with_llvm=no GO_CLIENT=1\n```\n\n`with_llvm=no` is necessary to disable llvm bit code generation when PostgreSQL is configured with `--with-llvm` because `influxdb_fdw` use go code and cannot be compiled to llvm bit code.\n\n#### Using `Influxdb_cxx` client\n```sh\nmake USE_PGXS=1 with_llvm=no CXX_CLIENT=1\nmake install USE_PGXS=1 with_llvm=no CXX_CLIENT=1\n```\n\nUsage\n-----\n\n## CREATE SERVER options\n\n`influxdb_fdw` accepts the following options via the `CREATE SERVER` command:\n\n- **dbname** as *string*, optional\n\nTarget database name.\n\n- **host** as *string*, optional\n\nThe address used to connect to InfluxDB server.\n\n- **port** as *integer*, optional\n\nThe port used to connect to InfluxDB server.\n\n- **version** as *integer*, optional, no default\n\nInfluxDB server version which to connect to. If not, InfluxDB FDW will try to connect to InfluxDB V2 first. If unsuccessful, it will try to connect to InfluxDB V1. If it is still unsuccessful, error will be raised.\nAvaillable values: `1` for InfluxDB ver 1.x and `2` for InfluxDB ver 2.x.\n\n- **retention_policy** as *string*, optional, default empty.\n\nRetention policy of target database. See in InfluxDB ver 2.x documentation.\n\n## CREATE USER MAPPING options\n\n`influxdb_fdw` accepts the following options via the `CREATE USER MAPPING`\ncommand:\n\n- **user** as *string*, no default\n\n  Username for V1 basic authentication (InfluxDB ver. 1.x).\n\n- **password** as *string*, no default\n\n  Password for V1 basic authentication (InfluxDB ver. 1.x).\n\n- **auth_token** as *string*, no default\n\n  Token for V2 Token authentication (InfluxDB ver. 2.x).\n\n## CREATE FOREIGN TABLE options\n\n`influxdb_fdw` accepts the following table-level options via the\n`CREATE FOREIGN TABLE` command.\n\n- **tags** as *string*, optional, no default\n\n- **table** as *string*, optional, no default\n\n- **schemaless** as *boolean*, optional, default `false`\n\n  Enable schemaless mode.\n\n## IMPORT FOREIGN SCHEMA options\n\n`influxdb_fdw` supports [IMPORT FOREIGN SCHEMA](https://www.postgresql.org/docs/current/sql-importforeignschema.html) and\n accepts the following options via the\n`IMPORT FOREIGN SCHEMA` command.\n\n- **schemaless** as *boolean*, optional, default `false`\n\n  Enable schemaless mode.\n\n## TRUNCATE support\n\n`influxdb_fdw` **don't support** the foreign data wrapper `TRUNCATE` API, available\nfrom PostgreSQL 14.\n\nFunctions\n---------\n\nAs well as the standard `influxdb_fdw_handler()` and `influxdb_fdw_validator()`\nfunctions, `influxdb_fdw` provides the following user-callable utility functions:\n\nListed as *type*, *name with arguments*, *returm datatype* where such function types are availlable:\n- **vf** - volatile functions\n- **a** - aggregations\n- **sf** - stable functions\n- **f** - simple function\n\n### Common functions\n- vf  'log2(float8)', 'float8'\n- vf  'log10(float8)', 'float8'\n\n### Special aggregations\n- a   'influx_count_all(*)', 'text'\n- a   'influx_count(text)', 'text'\n- a   'influx_distinct(anyelement)', 'anyelement'\n- a   'integral(bigint)', 'bigint'\n- a   'integral(float8)', 'float8'\n- a   'integral(bigint, interval)', 'bigint'\n- a   'integral(float8, interval)', 'float8'\n- a   'integral_all(*)', 'text'\n- a   'integral(text)', 'text'\n- a   'mean(bigint)', 'bigint'\n- a   'mean(float8)', 'float8'\n- a   'mean_all(*)', 'text'\n- a   'mean(text)', 'text'\n- a   'median(bigint)', 'bigint'\n- a   'median(float8)', 'float8'\n- a   'median_all(*)', 'text'\n- a   'median(text)', 'text'\n- a   'influx_mode(anyelement)', 'anyelement'\n- a   'influx_mode_all(*)', 'text'\n- a   'influx_mode(text)', 'text'\n- a   'spread(bigint)', 'bigint'\n- a   'spread(float8)', 'float8'\n- a   'spread_all(*)', 'text'\n- a   'spread(text)', 'text'\n- a   'stddev_all(*)', 'text'\n- a   'stddev(text)', 'text'\n- a   'influx_sum_all(*)', 'text'\n- a   'influx_sum(text)', 'text'\n\n### Selectors\n- f   'bottom(bigint, int)', 'float8'\n- f   'bottom(float8, int)', 'float8'\n- f   'bottom(bigint, text, int)', 'float8'\n- f   'bottom(float8, text, int)', 'float8'\n- a   'first(timestamp with time zone, anyelement)', 'anyelement'\n- a   'first_all(*)', 'text'\n- a   'first(text)', 'text'\n- a   'last(timestamp with time zone, anyelement)', 'anyelement'\n- a   'last_all(*)', 'text'\n- a   'last(text)', 'text'\n- a   'influx_max_all(*)', 'text'\n- a   'influx_max(text)', 'text'\n- a   'influx_min_all(*)', 'text'\n- a   'influx_min(text)', 'text'\n- f   'percentile(bigint, int)', 'float8'\n- f   'percentile(float8, int)', 'float8'\n- f   'percentile(bigint, float8)', 'float8'\n- f   'percentile(float8, float8)', 'float8'\n- sf  'percentile_all(int)', 'text'\n- sf  'percentile_all(float8)', 'text'\n- sf  'percentile(text, int)', 'text'\n- sf  'percentile(text, float8)', 'text'\n- a   'sample(anyelement, int)', 'anyelement'\n- sf  'sample_all(int)', 'text'\n- sf  'sample(text, int)', 'text'\n- f   'top(bigint, int)', 'float8'\n- f   'top(float8, int)', 'float8'\n- f   'top(bigint, text, int)', 'float8'\n- f   'top(float8, text, int)', 'float8'\n\n### Transformations\n- sf  'abs_all()', 'text'\n- sf  'acos_all()', 'text'\n- sf  'asin_all()', 'text'\n- sf  'atan_all()', 'text'\n- sf  'atan2_all(bigint)', 'text'\n- sf  'atan2_all(float8)', 'text'\n- sf  'ceil_all()', 'text'\n- sf  'cos_all()', 'text'\n- f   'cumulative_sum(bigint)', 'bigint'\n- f   'cumulative_sum(float8)', 'float8'\n- sf  'cumulative_sum_all()', 'text'\n- sf  'cumulative_sum(text)', 'text'\n- f   'derivative(anyelement)', 'anyelement'\n- f   'derivative(anyelement, interval)', 'anyelement'\n- sf  'derivative_all()', 'text'\n- sf  'derivative(text)', 'text'\n- f   'difference(bigint)', 'bigint'\n- f   'difference(float8)', 'float8'\n- sf  'difference_all()', 'text'\n- sf  'difference(text)', 'text'\n- f   'elapsed(anyelement)', 'bigint'\n- sf  'elapsed_all()', 'text'\n- sf  'elapsed(text)', 'text'\n- f   'elapsed(anyelement, interval)', 'bigint'\n- sf  'exp_all()', 'text'\n- sf  'floor_all()', 'text'\n- sf  'ln_all()', 'text'\n- sf  'log_all(bigint)', 'text'\n- sf  'log_all(float8)', 'text'\n- sf  'log2_all()', 'text'\n- sf  'log10_all()', 'text'\n- f   'moving_average(bigint, int)', 'float8'\n- f   'moving_average(float8, int)', 'float8'\n- sf  'moving_average_all(int)', 'text'\n- sf  'moving_average(text, int)', 'text'\n- f   'non_negative_derivative(anyelement)', 'anyelement'\n- f   'non_negative_derivative(anyelement, interval)', 'anyelement'\n- sf  'non_negative_derivative_all()', 'text'\n- sf  'non_negative_derivative(text)', 'text'\n- f   'non_negative_difference(bigint)', 'bigint'\n- f   'non_negative_difference(float8)', 'float8'\n- sf  'non_negative_difference_all()', 'text'\n- sf  'non_negative_difference(text)', 'text'\n- sf  'pow_all(int)', 'text'\n- sf  'round_all()', 'text'\n- sf  'sin_all()', 'text'\n- sf  'sqrt_all()', 'text'\n- sf  'tan_all()', 'text'\n\n### Predictors\n- f   'holt_winters(anyelement, int, int)', 'anyelement'\n- f   'holt_winters_with_fit(anyelement, int, int)', 'anyelement'\n\n### Technical Analysis\n- f   'chande_momentum_oscillator(bigint, int)', 'float8'\n- f   'chande_momentum_oscillator(float8, int)', 'float8'\n- f   'chande_momentum_oscillator(bigint, int, int)', 'float8'\n- f   'chande_momentum_oscillator(float8, int, int)', 'float8'\n- f   'chande_momentum_oscillator(double precision, int)', 'float8'\n- f   'chande_momentum_oscillator(double precision, int, int)', 'float8'\n- sf  'chande_momentum_oscillator_all(int)', 'text'\n- sf  'chande_momentum_oscillator(text, int)', 'text'\n- f   'exponential_moving_average(bigint, int)', 'float8'\n- f   'exponential_moving_average(float8, int)', 'float8'\n- f   'exponential_moving_average(bigint, int, int)', 'float8'\n- f   'exponential_moving_average(float8, int, int)', 'float8'\n- sf  'exponential_moving_average_all(int)', 'text'\n- sf  'exponential_moving_average(text, int)', 'text'\n- f   'double_exponential_moving_average(bigint, int)', 'float8'\n- f   'double_exponential_moving_average(float8, int)', 'float8'\n- f   'double_exponential_moving_average(bigint, int, int)', 'float8'\n- f   'double_exponential_moving_average(float8, int, int)', 'float8'\n- sf  'double_exponential_moving_average_all(int)', 'text'\n- sf  'double_exponential_moving_average(text, int)', 'text'\n- f   'kaufmans_efficiency_ratio(bigint, int)', 'float8'\n- f   'kaufmans_efficiency_ratio(float8, int)', 'float8'\n- f   'kaufmans_efficiency_ratio(bigint, int, int)', 'float8'\n- f   'kaufmans_efficiency_ratio(float8, int, int)', 'float8'\n- sf  'kaufmans_efficiency_ratio_all(int)', 'text'\n- sf  'kaufmans_efficiency_ratio(text, int)', 'text'\n- f   'kaufmans_adaptive_moving_average(bigint, int)', 'float8'\n- f   'kaufmans_adaptive_moving_average(float8, int)', 'float8'\n- f   'kaufmans_adaptive_moving_average(bigint, int, int)', 'float8'\n- f   'kaufmans_adaptive_moving_average(float8, int, int)', 'float8'\n- sf  'kaufmans_adaptive_moving_average_all(int)', 'text'\n- sf  'kaufmans_adaptive_moving_average(text, int)', 'text'\n- f   'triple_exponential_moving_average(bigint, int)', 'float8'\n- f   'triple_exponential_moving_average(float8, int)', 'float8'\n- f   'triple_exponential_moving_average(bigint, int, int)', 'float8'\n- f   'triple_exponential_moving_average(float8, int, int)', 'float8'\n- sf  'triple_exponential_moving_average_all(int)', 'text'\n- sf  'triple_exponential_moving_average(text, int)', 'text'\n- f   'triple_exponential_derivative(bigint, int)', 'float8'\n- f   'triple_exponential_derivative(float8, int)', 'float8'\n- f   'triple_exponential_derivative(bigint, int, int)', 'float8'\n- f   'triple_exponential_derivative(float8, int, int)', 'float8'\n- sf  'triple_exponential_derivative_all(int)', 'text'\n- sf  'triple_exponential_derivative(text, int)', 'text'\n- f   'relative_strength_index(bigint, int)', 'float8'\n- f   'relative_strength_index(float8, int)', 'float8'\n- f   'relative_strength_index(bigint, int, int)', 'float8'\n- f   'relative_strength_index(float8, int, int)', 'float8'\n- sf  'relative_strength_index_all(int)', 'text'\n- sf  'relative_strength_index(text, int)', 'text'\n\n### Special time functions\n- f   'influx_time(timestamp with time zone, interval, interval)', 'timestamp with time zone'\n- f   'influx_time(timestamp with time zone, interval)', 'timestamp with time zone'\n- f   'influx_time(timestamp with time zone, interval, interval, anyelement)', 'timestamp with time zone'\n- f   'influx_time(timestamp with time zone, interval, anyelement)', 'timestamp with time zone'\n- sf  'influx_fill_option(influx_fill_enum)', 'int'\n- sf  'influx_fill_numeric(float8)', 'float8'\n- sf  'influx_fill_numeric(int)', 'int'\n\nIdentifier case handling\n------------------------\n\nPostgreSQL folds identifiers to lower case by default.\nRules and problems with InfluxDB identifiers **yet not tested and described**.\n\nGenerated columns\n-----------------\n\nBehavoiur within generated columns **yet not tested and described**.\n\nFor more details on generated columns see:\n\n- [Generated Columns](https://www.postgresql.org/docs/current/ddl-generated-columns.html)\n- [CREATE FOREIGN TABLE](https://www.postgresql.org/docs/current/sql-createforeigntable.html)\n\n\nCharacter set handling\n----------------------\n\n**Yet not described**. Strongly recommended to use any of Unicode encodings for PostgreSQL with `influxdb_fdw`.\n\nExamples\n--------\n\n### Install the extension:\n\nOnce for a database you need, as PostgreSQL superuser.\n\n```sql\n\tCREATE EXTENSION influxdb_fdw;\n```\n\n### Create a foreign server with appropriate configuration:\n\nOnce for a foreign datasource you need, as PostgreSQL superuser. Please specify database name using `dbname` option.\n\n#### Go Client connect to InfluxDB ver 1.x\n```sql\n\tCREATE SERVER influxdb_svr\n\tFOREIGN DATA WRAPPER influxdb_fdw\n\tOPTIONS (\n          dbname 'mydb',\n\t  host 'http://localhost',\n\t  port '8086'\n\t);\n```\n#### `Influxdb_cxx` Client connect to InfluxDB ver 1.x\n```sql\n\tCREATE SERVER influxdb_svr\n\tFOREIGN DATA WRAPPER influxdb_fdw\n\tOPTIONS (\n          dbname 'mydb',\n\t  host 'http://localhost',\n\t  port '8086',\n\t  version '1'\n\t);\n```\n#### `Influxdb_cxx` Client connect to InfluxDB ver 2.x\n```sql\n\tCREATE SERVER influxdb_svr\n\tFOREIGN DATA WRAPPER influxdb_fdw\n\tOPTIONS (\n          dbname 'mydb',\n\t  host 'http://localhost',\n\t  port '8086',\n\t  version '2',\n\t  retention_policy ''\n\t);\n```\n\n### Grant usage on foreign server to normal user in PostgreSQL:\n\nOnce for a normal user (non-superuser) in PostgreSQL, as PostgreSQL superuser. It is a good idea to use a superuser only where really necessary, so let's allow a normal user to use the foreign server (this is not required for the example to work, but it's secirity recomedation).\n\n```sql\n\tGRANT USAGE ON FOREIGN SERVER influxdb_svr TO pguser;\n```\nWhere `pguser` is a sample user for works with foreign server (and foreign tables).\n\n### User mapping\n\nCreate an appropriate user mapping:\n\n#### Go Client connect to InfluxDB ver 1.x\n\n```sql\n    \tCREATE USER MAPPING\n\tFOR pguser\n\tSERVER influxdb_svr\n    \tOPTIONS (\n\t  user 'username',\n\t  password 'password'\n\t);\n```\nWhere `pguser` is a sample user for works with foreign server (and foreign tables).\n\n#### `Influxdb_cxx` Client connect to InfluxDB ver 1.x\n\n```sql\n    \tCREATE USER MAPPING\n\tFOR pguser\n\tSERVER influxdb_svr\n    \tOPTIONS (\n\t  user 'username',\n\t  password 'password'\n\t);\n```\nWhere `pguser` is a sample user for works with foreign server (and foreign tables).\n\n#### `Influxdb_cxx` Client connect to InfluxDB ver 2.x\n\n```sql\n    \tCREATE USER MAPPING\n\tFOR pguser\n\tSERVER influxdb_svr\n    \tOPTIONS (\n\t  auth_token 'token'\n\t);\n```\nWhere `pguser` is a sample user for works with foreign server (and foreign tables).\n\n### Create foreign table\nAll `CREATE FOREIGN TABLE` SQL commands can be executed as a normal PostgreSQL user if there were correct `GRANT USAGE ON FOREIGN SERVER`. No need PostgreSQL supersuer for security reasons but also works with PostgreSQL supersuer.\n\nCreate a foreign table referencing the InfluxDB table:\nYou need to declare a column named `time` to access InfluxDB time column.\n```sql\n\tCREATE FOREIGN TABLE t1(\n\t  time timestamp with time zone,\n\t  tag1 text,\n\t  field1 integer\n\t)\n\tSERVER influxdb_svr\n\tOPTIONS (\n\t  table 'measurement1'\n\t);\n```\nYou can use `tags` option to specify tag keys of a foreign table.\n```sql\n\tCREATE FOREIGN TABLE t2(\n\t  tag1 text,\n\t  field1 integer,\n\t  tag2 text,\n\t  field2 integer\n\t)\n\tSERVER influxdb_svr\n\tOPTIONS (\n\t  tags 'tag1, tag2'\n\t);\n```\nYou can import foreign schema\n```sql\n\tIMPORT FOREIGN SCHEMA public\n\tFROM SERVER influxdb_svr\n\tINTO public;\n```\nAccess foreign table\n```sql\n\tSELECT * FROM t1;\n```\n\nLimitations\n-----------\n\n- `UPDATE` is not supported.\n- `WITH CHECK OPTION` constraints is not supported.\n\n### Limitations originate from data model and query language of *InfluxDB*\n\n- Result sets have different number of rows depending on specified target list.\nFor example, `SELECT field1 FROM t1` and `SELECT field2 FROM t1` returns different number of rows if\nthe number of points with field1 and field2 are different in *InfluxDB* database.\n- Timestamp precision may be lost because timestamp resolution of PostgreSQL is microseconds while that of *InfluxDB* is nanoseconds.\n- Conditions like `WHERE time + interval '1 day' \u003c now()` do not work. Please use `WHERE time \u003c now() - interval '1 day'`.\n- InfluxDB FDW does not return an error even if it is overflow.\n- `EXP` function of *InfluxDB* may return different precision number for different PC.\n- InfluxDB only supports some basic types for tags (string only) and fields (string, float, integer or boolean) =\u003e most Postgres types cannot be supported.\n- `IMPORT FOREIGN SCHEMA` should be used to identify foreign tables.\n  - If the user defines it manually, it is necessary to use the correct mapping type in the foreign table to avoid some unexpected behavior because of type mismatch or unsupported in InfluxDB.\n  - If a user wants to use an unsupported type with InfluxDB data, PostgreSQL's explicit cast functions should be used instead of define column type in foreign table directly.\n- For pattern matching, Regex pattern of Postgres and InfluxDB has some differences. For example,\n  - Postgres supports patterns \\m, \\M but InfluxDB does not.\n  - InfluxDB supports patterns (?U) ungreedy, \\Q...\\E but Postgres does not.\nIf Postgres detects invalid pattern, it will report error. Otherwise, FDW will push down the pattern to InfluxDB. If InfluxDB detects invalid pattern, it will report error. Otherwise, it will search data matching the pattern and return result to user.\n\nWhen a query to foreign tables fails, you can find why it fails by seeing a query executed in *InfluxDB* with `EXPLAIN VERBOSE`.\n\nContributing\n------------\nOpening issues and pull requests on GitHub are welcome. Test scripts is multiversional for PostgreSQL, works in POSIX context and based on comparing output of SQL commands in psql with expected output text files.\nCurrent test expected results are generated based on results in `Rocky Linux 8` and its default `glibc 2.28`. Test results may fail with other version of `glibc` with the following cases.\n  - Different order of records due to string collation changes\n  - Minor change of float number after decimal point due to different floating point calculation\n\n\nUseful links\n------------\n\n### Source code\n\nReference FDW realisation, `postgres_fdw`\n - https://git.postgresql.org/gitweb/?p=postgresql.git;a=tree;f=contrib/postgres_fdw;hb=HEAD\n\n### General FDW Documentation\n\n - https://www.postgresql.org/docs/current/ddl-foreign-data.html\n - https://www.postgresql.org/docs/current/sql-createforeigndatawrapper.html\n - https://www.postgresql.org/docs/current/sql-createforeigntable.html\n - https://www.postgresql.org/docs/current/sql-importforeignschema.html\n - https://www.postgresql.org/docs/current/fdwhandler.html\n - https://www.postgresql.org/docs/current/postgres-fdw.html\n\n### Other FDWs\n\n - https://wiki.postgresql.org/wiki/Fdw\n - https://pgxn.org/tag/fdw/\n \nLicense\n-------\n\nCopyright (c) 2018, TOSHIBA CORPORATION\n\nCopyright (c) 2011-2016, EnterpriseDB Corporation\n\nPermission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.\n\nSee the [`LICENSE`](LICENSE) file for full details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgspider%2Finfluxdb_fdw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgspider%2Finfluxdb_fdw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgspider%2Finfluxdb_fdw/lists"}