├── .gitignore ├── sql ├── parameters.conf ├── 15.7 │ ├── server_options.sql │ ├── extra │ │ ├── delete.sql │ │ └── insert.sql │ ├── dynamodb_fdw.sql │ └── connection_validation.sql ├── 16.3 │ ├── server_options.sql │ ├── extra │ │ ├── delete.sql │ │ └── insert.sql │ ├── dynamodb_fdw.sql │ └── connection_validation.sql ├── 17.0 │ ├── server_options.sql │ ├── extra │ │ ├── delete.sql │ │ └── insert.sql │ ├── dynamodb_fdw.sql │ └── connection_validation.sql ├── 13.15 │ ├── server_options.sql │ ├── extra │ │ ├── delete.sql │ │ └── insert.sql │ ├── dynamodb_fdw.sql │ └── connection_validation.sql └── 14.12 │ ├── server_options.sql │ ├── extra │ ├── delete.sql │ └── insert.sql │ ├── dynamodb_fdw.sql │ └── connection_validation.sql ├── dynamodb_fdw.control ├── dynamodb_fdw--1.0--1.1.sql ├── test.sh ├── jansson ├── utf.h ├── strbuffer.h ├── memory.c ├── jansson_config.h ├── error.c ├── strbuffer.c ├── jansson_private.h ├── strconv.c ├── utf.c ├── hashtable.h ├── jansson_private_config.h └── hashtable_seed.c ├── dynamodb_query.hpp ├── LICENSE ├── dynamodb_fdw.hpp ├── META.json ├── Makefile ├── expected ├── 13.15 │ ├── server_options.out │ └── dynamodb_fdw.out ├── 14.12 │ ├── server_options.out │ └── dynamodb_fdw.out ├── 15.7 │ ├── server_options.out │ └── dynamodb_fdw.out ├── 16.3 │ ├── server_options.out │ └── dynamodb_fdw.out └── 17.0 │ ├── server_options.out │ └── dynamodb_fdw.out ├── dynamodb_fdw--1.0.sql ├── dynamodb_fdw.h ├── dynamodb_fdw.c ├── option.c └── shippable.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated subdirectories 2 | /log/ 3 | /results/ 4 | /tmp_check/ 5 | *.o 6 | *.so 7 | -------------------------------------------------------------------------------- /sql/parameters.conf: -------------------------------------------------------------------------------- 1 | \set DYNAMODB_ENDPOINT '''http://localhost:8000''' 2 | \set DYNAMODB_USER '''admin''' 3 | \set DYNAMODB_PASSWORD '''testadmin''' -------------------------------------------------------------------------------- /dynamodb_fdw.control: -------------------------------------------------------------------------------- 1 | # dynamodb_fdw extension 2 | comment = 'foreign-data wrapper for DynamoDB' 3 | default_version = '1.1' 4 | module_pathname = '$libdir/dynamodb_fdw' 5 | relocatable = true 6 | -------------------------------------------------------------------------------- /dynamodb_fdw--1.0--1.1.sql: -------------------------------------------------------------------------------- 1 | /* contrib/dynamodb_fdw/dynamodb_fdw--1.0--1.1.sql */ 2 | 3 | CREATE OR REPLACE FUNCTION dynamodb_fdw_version() 4 | RETURNS pg_catalog.int4 STRICT 5 | AS 'MODULE_PATHNAME' LANGUAGE C; 6 | 7 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf init.log || true 4 | ./dynamodb_init.sh > init.log 5 | 6 | sed -i 's/REGRESS =.*/REGRESS = server_options connection_validation dynamodb_fdw pushdown extra\/delete extra\/insert extra\/json extra\/jsonb extra\/select extra\/update /' Makefile 7 | 8 | make clean 9 | make 10 | mkdir -p results/extra 11 | make check $1| tee make_check.out 12 | -------------------------------------------------------------------------------- /jansson/utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef UTF_H 9 | #define UTF_H 10 | 11 | #ifdef HAVE_CONFIG_H 12 | #include 13 | #endif 14 | 15 | #ifdef HAVE_STDINT_H 16 | #include 17 | #endif 18 | 19 | int utf8_encode(int32_t codepoint, char *buffer, size_t *size); 20 | 21 | size_t utf8_check_first(char byte); 22 | size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint); 23 | const char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint); 24 | 25 | int utf8_check_string(const char *string, size_t length); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /dynamodb_query.hpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * dynamodb_query.hpp 4 | * Header file for type handling for DynamoDB Foreign Data Wrapper 5 | * 6 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 7 | * 8 | * IDENTIFICATION 9 | * contrib/dynamodb_fdw/dynamodb_query.hpp 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | extern "C" 14 | { 15 | #include "postgres.h" 16 | #include "utils/builtins.h" 17 | } 18 | 19 | #include 20 | #include 21 | 22 | Datum 23 | dynamodb_convert_to_pg(Oid pgtyp, int pgtypmod, Aws::DynamoDB::Model::AttributeValue dynamodbVal); 24 | 25 | Aws::DynamoDB::Model::AttributeValue 26 | dynamodb_bind_sql_var(Oid type, int attnum, Datum value, const char * query, bool isnull); -------------------------------------------------------------------------------- /jansson/strbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef STRBUFFER_H 9 | #define STRBUFFER_H 10 | 11 | #include 12 | 13 | typedef struct { 14 | char *value; 15 | size_t length; /* bytes used */ 16 | size_t size; /* bytes allocated */ 17 | } strbuffer_t; 18 | 19 | int strbuffer_init(strbuffer_t *strbuff) JANSSON_ATTRS(warn_unused_result); 20 | void strbuffer_close(strbuffer_t *strbuff); 21 | 22 | void strbuffer_clear(strbuffer_t *strbuff); 23 | 24 | const char *strbuffer_value(const strbuffer_t *strbuff); 25 | 26 | /* Steal the value and close the strbuffer */ 27 | char *strbuffer_steal_value(strbuffer_t *strbuff); 28 | 29 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte); 30 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size); 31 | 32 | char strbuffer_pop(strbuffer_t *strbuff); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DynamoDB Foreign Data Wrapper for PostgreSQL 2 | 3 | Copyright (c) 2021, TOSHIBA Corporation 4 | 5 | Permission to use, copy, modify, and distribute this software and its 6 | documentation for any purpose, without fee, and without a written agreement is 7 | hereby granted, provided that the above copyright notice and this paragraph and 8 | the following two paragraphs appear in all copies. 9 | 10 | IN NO EVENT SHALL TOSHIBA CORPORATION BE LIABLE TO ANY PARTY FOR 11 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 12 | PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 13 | TOSHIBA CORPORATION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | TOSHIBA CORPORATION SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 16 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 17 | PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 18 | TOSHIBA CORPORATION HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, 19 | UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 20 | -------------------------------------------------------------------------------- /dynamodb_fdw.hpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * dynamodb_fdw.hpp 4 | * Header file of dynamodb_fdw 5 | * 6 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 7 | * 8 | * IDENTIFICATION 9 | * contrib/dynamodb_fdw/dynamodb_fdw.hpp 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | #ifndef __DYNAMODB_FDW_HPP__ 14 | #define __DYNAMODB_FDW_HPP__ 15 | 16 | #include 17 | #include 18 | 19 | extern "C" 20 | { 21 | #include "postgres.h" 22 | #include "foreign/foreign.h" 23 | #include "dynamodb_fdw.h" 24 | } 25 | 26 | #define IS_KEY_EMPTY(key) \ 27 | (key == NULL || ((const Aws::String) key).size() == 0) 28 | 29 | #define IS_KEY_COLUMN(attname, key_name) (!IS_KEY_EMPTY(key_name) && strcmp(key_name, attname) == 0) 30 | 31 | extern Aws::DynamoDB::DynamoDBClient *dynamodb_get_connection(UserMapping *user); 32 | extern void dynamodb_report_error(int elevel, const Aws::String message, char* query); 33 | extern void dynamodb_release_connection(Aws::DynamoDB::DynamoDBClient *dynamoDB_client); 34 | 35 | #endif /* __DYNAMODB_FDW_HPP__ */ -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dynamodb_fdw", 3 | "abstract": "Foreign Data Wrapper for DynamoDB", 4 | "description": "PostgreSQL extension which implements a Foreign Data Wrapper (FDW) for DynamoDB.", 5 | "version": "2.1.1", 6 | "maintainer": "pgspider", 7 | "license": "postgresql", 8 | "provides": { 9 | "dynamodb_fdw": { 10 | "abstract": "Foreign Data Wrapper for DynamoDB", 11 | "file": "dynamodb_fdw.c", 12 | "docfile": "README.md", 13 | "version": "2.1.1" 14 | } 15 | }, 16 | "prereqs": { 17 | "runtime": { 18 | "requires": { 19 | "PostgreSQL": "9.6.0" 20 | } 21 | } 22 | }, 23 | "resources": { 24 | "bugtracker": { 25 | "web": "http://github.com/pgspider/dynamodb_fdw/issues/" 26 | }, 27 | "repository": { 28 | "url": "git://github.com/pgspider/dynamodb_fdw.git", 29 | "web": "https://github.com/pgspider/dynamodb_fdw/", 30 | "type": "git" 31 | } 32 | }, 33 | "generated_by": "David E. Wheeler", 34 | "meta-spec": { 35 | "version": "1.0.0", 36 | "url": "http://pgxn.org/meta/spec.txt" 37 | }, 38 | "tags": [ 39 | "dynamo", 40 | "dynamodb", 41 | "fdw", 42 | "foreign data wrapper", 43 | "dynamodb_fdw" 44 | ] 45 | } -------------------------------------------------------------------------------- /jansson/memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * Copyright (c) 2011-2012 Basile Starynkevitch 4 | * 5 | * Jansson is free software; you can redistribute it and/or modify it 6 | * under the terms of the MIT license. See LICENSE for details. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "jansson.h" 13 | #include "jansson_private.h" 14 | 15 | /* C89 allows these to be macros */ 16 | #undef malloc 17 | #undef free 18 | 19 | /* memory function pointers */ 20 | static json_malloc_t do_malloc = malloc; 21 | static json_free_t do_free = free; 22 | 23 | void *jsonp_malloc(size_t size) 24 | { 25 | if(!size) 26 | return NULL; 27 | 28 | return (*do_malloc)(size); 29 | } 30 | 31 | void jsonp_free(void *ptr) 32 | { 33 | if(!ptr) 34 | return; 35 | 36 | (*do_free)(ptr); 37 | } 38 | 39 | char *jsonp_strdup(const char *str) 40 | { 41 | return jsonp_strndup(str, strlen(str)); 42 | } 43 | 44 | char *jsonp_strndup(const char *str, size_t len) 45 | { 46 | char *new_str; 47 | 48 | new_str = jsonp_malloc(len + 1); 49 | if(!new_str) 50 | return NULL; 51 | 52 | memcpy(new_str, str, len); 53 | new_str[len] = '\0'; 54 | return new_str; 55 | } 56 | 57 | void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn) 58 | { 59 | do_malloc = malloc_fn; 60 | do_free = free_fn; 61 | } 62 | 63 | void json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn) 64 | { 65 | if (malloc_fn) 66 | *malloc_fn = do_malloc; 67 | if (free_fn) 68 | *free_fn = do_free; 69 | } 70 | -------------------------------------------------------------------------------- /jansson/jansson_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | * 7 | * 8 | * This file specifies a part of the site-specific configuration for 9 | * Jansson, namely those things that affect the public API in 10 | * jansson.h. 11 | * 12 | * The configure script copies this file to jansson_config.h and 13 | * replaces @var@ substitutions by values that fit your system. If you 14 | * cannot run the configure script, you can do the value substitution 15 | * by hand. 16 | */ 17 | 18 | #ifndef JANSSON_CONFIG_H 19 | #define JANSSON_CONFIG_H 20 | 21 | /* If your compiler supports the inline keyword in C, JSON_INLINE is 22 | defined to `inline', otherwise empty. In C++, the inline is always 23 | supported. */ 24 | #ifdef __cplusplus 25 | #define JSON_INLINE inline 26 | #else 27 | #define JSON_INLINE inline 28 | #endif 29 | 30 | /* If your compiler supports the `long long` type and the strtoll() 31 | library function, JSON_INTEGER_IS_LONG_LONG is defined to 1, 32 | otherwise to 0. */ 33 | #define JSON_INTEGER_IS_LONG_LONG 1 34 | 35 | /* If locale.h and localeconv() are available, define to 1, 36 | otherwise to 0. */ 37 | #define JSON_HAVE_LOCALECONV 1 38 | 39 | /* If __atomic builtins are available they will be used to manage 40 | reference counts of json_t. */ 41 | #define JSON_HAVE_ATOMIC_BUILTINS 1 42 | 43 | /* If __atomic builtins are not available we try using __sync builtins 44 | to manage reference counts of json_t. */ 45 | #define JSON_HAVE_SYNC_BUILTINS 1 46 | 47 | /* Maximum recursion depth for parsing JSON input. 48 | This limits the depth of e.g. array-within-array constructions. */ 49 | #define JSON_PARSER_MAX_DEPTH 2048 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /jansson/error.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "jansson_private.h" 3 | 4 | void jsonp_error_init(json_error_t *error, const char *source) 5 | { 6 | if(error) 7 | { 8 | error->text[0] = '\0'; 9 | error->line = -1; 10 | error->column = -1; 11 | error->position = 0; 12 | if(source) 13 | jsonp_error_set_source(error, source); 14 | else 15 | error->source[0] = '\0'; 16 | } 17 | } 18 | 19 | void jsonp_error_set_source(json_error_t *error, const char *source) 20 | { 21 | size_t length; 22 | 23 | if(!error || !source) 24 | return; 25 | 26 | length = strlen(source); 27 | if(length < JSON_ERROR_SOURCE_LENGTH) 28 | strncpy(error->source, source, length + 1); 29 | else { 30 | size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; 31 | memcpy(error->source, "...", 3); 32 | strncpy(error->source + 3, source + extra, length - extra + 1); 33 | } 34 | } 35 | 36 | void jsonp_error_set(json_error_t *error, int line, int column, 37 | size_t position, enum json_error_code code, 38 | const char *msg, ...) 39 | { 40 | va_list ap; 41 | 42 | va_start(ap, msg); 43 | jsonp_error_vset(error, line, column, position, code, msg, ap); 44 | va_end(ap); 45 | } 46 | 47 | void jsonp_error_vset(json_error_t *error, int line, int column, 48 | size_t position, enum json_error_code code, 49 | const char *msg, va_list ap) 50 | { 51 | if(!error) 52 | return; 53 | 54 | if(error->text[0] != '\0') { 55 | /* error already set */ 56 | return; 57 | } 58 | 59 | error->line = line; 60 | error->column = column; 61 | error->position = (int)position; 62 | 63 | vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH - 1, msg, ap); 64 | error->text[JSON_ERROR_TEXT_LENGTH - 2] = '\0'; 65 | error->text[JSON_ERROR_TEXT_LENGTH - 1] = code; 66 | } 67 | -------------------------------------------------------------------------------- /sql/15.7/server_options.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Validate extension, server and mapping details 17 | --Testcase 4: 18 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 19 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 20 | WHERE e.fdwname = 'dynamodb_fdw' 21 | ORDER BY 1, 2, 3, 4; 22 | 23 | -- Create foreign tables and perform basic SQL operations 24 | --Testcase 5: 25 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 26 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 27 | --Testcase 6: 28 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 29 | --Testcase 7: 30 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 33 | --Testcase 9: 34 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 35 | --Testcase 10: 36 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 37 | --Testcase 11: 38 | DELETE FROM server_option_tbl WHERE artist = '0000'; 39 | --Testcase 12: 40 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 41 | 42 | -- Cleanup 43 | --Testcase 13: 44 | DROP FOREIGN TABLE server_option_tbl; 45 | --Testcase 14: 46 | DROP USER MAPPING FOR public SERVER dynamodb_server; 47 | --Testcase 15: 48 | DROP SERVER dynamodb_server; 49 | --Testcase 16: 50 | DROP EXTENSION dynamodb_fdw; 51 | -------------------------------------------------------------------------------- /sql/16.3/server_options.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Validate extension, server and mapping details 17 | --Testcase 4: 18 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 19 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 20 | WHERE e.fdwname = 'dynamodb_fdw' 21 | ORDER BY 1, 2, 3, 4; 22 | 23 | -- Create foreign tables and perform basic SQL operations 24 | --Testcase 5: 25 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 26 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 27 | --Testcase 6: 28 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 29 | --Testcase 7: 30 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 33 | --Testcase 9: 34 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 35 | --Testcase 10: 36 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 37 | --Testcase 11: 38 | DELETE FROM server_option_tbl WHERE artist = '0000'; 39 | --Testcase 12: 40 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 41 | 42 | -- Cleanup 43 | --Testcase 13: 44 | DROP FOREIGN TABLE server_option_tbl; 45 | --Testcase 14: 46 | DROP USER MAPPING FOR public SERVER dynamodb_server; 47 | --Testcase 15: 48 | DROP SERVER dynamodb_server; 49 | --Testcase 16: 50 | DROP EXTENSION dynamodb_fdw; 51 | -------------------------------------------------------------------------------- /sql/17.0/server_options.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Validate extension, server and mapping details 17 | --Testcase 4: 18 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 19 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 20 | WHERE e.fdwname = 'dynamodb_fdw' 21 | ORDER BY 1, 2, 3, 4; 22 | 23 | -- Create foreign tables and perform basic SQL operations 24 | --Testcase 5: 25 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 26 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 27 | --Testcase 6: 28 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 29 | --Testcase 7: 30 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 33 | --Testcase 9: 34 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 35 | --Testcase 10: 36 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 37 | --Testcase 11: 38 | DELETE FROM server_option_tbl WHERE artist = '0000'; 39 | --Testcase 12: 40 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 41 | 42 | -- Cleanup 43 | --Testcase 13: 44 | DROP FOREIGN TABLE server_option_tbl; 45 | --Testcase 14: 46 | DROP USER MAPPING FOR public SERVER dynamodb_server; 47 | --Testcase 15: 48 | DROP SERVER dynamodb_server; 49 | --Testcase 16: 50 | DROP EXTENSION dynamodb_fdw; 51 | -------------------------------------------------------------------------------- /sql/13.15/server_options.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Validate extension, server and mapping details 17 | --Testcase 4: 18 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 19 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 20 | WHERE e.fdwname = 'dynamodb_fdw' 21 | ORDER BY 1, 2, 3, 4; 22 | 23 | -- Create foreign tables and perform basic SQL operations 24 | --Testcase 5: 25 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 26 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 27 | --Testcase 6: 28 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 29 | --Testcase 7: 30 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 33 | --Testcase 9: 34 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 35 | --Testcase 10: 36 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 37 | --Testcase 11: 38 | DELETE FROM server_option_tbl WHERE artist = '0000'; 39 | --Testcase 12: 40 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 41 | 42 | -- Cleanup 43 | --Testcase 13: 44 | DROP FOREIGN TABLE server_option_tbl; 45 | --Testcase 14: 46 | DROP USER MAPPING FOR public SERVER dynamodb_server; 47 | --Testcase 15: 48 | DROP SERVER dynamodb_server; 49 | --Testcase 16: 50 | DROP EXTENSION dynamodb_fdw; 51 | -------------------------------------------------------------------------------- /sql/14.12/server_options.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Validate extension, server and mapping details 17 | --Testcase 4: 18 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 19 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 20 | WHERE e.fdwname = 'dynamodb_fdw' 21 | ORDER BY 1, 2, 3, 4; 22 | 23 | -- Create foreign tables and perform basic SQL operations 24 | --Testcase 5: 25 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 26 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 27 | --Testcase 6: 28 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 29 | --Testcase 7: 30 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 33 | --Testcase 9: 34 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 35 | --Testcase 10: 36 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 37 | --Testcase 11: 38 | DELETE FROM server_option_tbl WHERE artist = '0000'; 39 | --Testcase 12: 40 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 41 | 42 | -- Cleanup 43 | --Testcase 13: 44 | DROP FOREIGN TABLE server_option_tbl; 45 | --Testcase 14: 46 | DROP USER MAPPING FOR public SERVER dynamodb_server; 47 | --Testcase 15: 48 | DROP SERVER dynamodb_server; 49 | --Testcase 16: 50 | DROP EXTENSION dynamodb_fdw; 51 | -------------------------------------------------------------------------------- /sql/13.15/extra/delete.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | --Testcase 4: 17 | CREATE FOREIGN TABLE delete_test (id SERIAL, a INT, b text) SERVER dynamodb_server OPTIONS (table_name 'delete_test', partition_key 'id'); 18 | 19 | --Testcase 5: 20 | EXPLAIN VERBOSE 21 | INSERT INTO delete_test (a) VALUES (10); 22 | --Testcase 6: 23 | INSERT INTO delete_test (a) VALUES (10); 24 | 25 | --Testcase 7: 26 | EXPLAIN VERBOSE 27 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 28 | --Testcase 8: 29 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 30 | 31 | --Testcase 9: 32 | EXPLAIN VERBOSE 33 | INSERT INTO delete_test (a) VALUES (100); 34 | --Testcase 10: 35 | INSERT INTO delete_test (a) VALUES (100); 36 | 37 | 38 | -- allow an alias to be specified for DELETE's target table 39 | --Testcase 11: 40 | EXPLAIN VERBOSE 41 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 42 | --Testcase 12: 43 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 44 | 45 | 46 | -- if an alias is specified, don't allow the original table name 47 | -- to be referenced 48 | --Testcase 13: 49 | EXPLAIN VERBOSE 50 | DELETE FROM delete_test dt WHERE dt.a > 25; 51 | 52 | --Testcase 14: 53 | DELETE FROM delete_test dt WHERE dt.a > 25; 54 | 55 | --Testcase 15: 56 | EXPLAIN VERBOSE 57 | SELECT id, a, char_length(b) FROM delete_test; 58 | --Testcase 16: 59 | SELECT id, a, char_length(b) FROM delete_test; 60 | 61 | 62 | -- delete a row with a TOASTed value 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | DELETE FROM delete_test WHERE a > 25; 66 | --Testcase 18: 67 | DELETE FROM delete_test WHERE a > 25; 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | SELECT id, a, char_length(b) FROM delete_test; 72 | --Testcase 20: 73 | SELECT id, a, char_length(b) FROM delete_test; 74 | 75 | --Testcase 21: 76 | DROP FOREIGN TABLE delete_test; 77 | 78 | 79 | --Testcase 22: 80 | DROP USER MAPPING FOR public SERVER dynamodb_server; 81 | --Testcase 23: 82 | DROP EXTENSION dynamodb_fdw CASCADE; 83 | -------------------------------------------------------------------------------- /sql/14.12/extra/delete.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | --Testcase 4: 17 | CREATE FOREIGN TABLE delete_test (id SERIAL, a INT, b text) SERVER dynamodb_server OPTIONS (table_name 'delete_test', partition_key 'id'); 18 | 19 | --Testcase 5: 20 | EXPLAIN VERBOSE 21 | INSERT INTO delete_test (a) VALUES (10); 22 | --Testcase 6: 23 | INSERT INTO delete_test (a) VALUES (10); 24 | 25 | --Testcase 7: 26 | EXPLAIN VERBOSE 27 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 28 | --Testcase 8: 29 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 30 | 31 | --Testcase 9: 32 | EXPLAIN VERBOSE 33 | INSERT INTO delete_test (a) VALUES (100); 34 | --Testcase 10: 35 | INSERT INTO delete_test (a) VALUES (100); 36 | 37 | 38 | -- allow an alias to be specified for DELETE's target table 39 | --Testcase 11: 40 | EXPLAIN VERBOSE 41 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 42 | --Testcase 12: 43 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 44 | 45 | 46 | -- if an alias is specified, don't allow the original table name 47 | -- to be referenced 48 | --Testcase 13: 49 | EXPLAIN VERBOSE 50 | DELETE FROM delete_test dt WHERE dt.a > 25; 51 | 52 | --Testcase 14: 53 | DELETE FROM delete_test dt WHERE dt.a > 25; 54 | 55 | --Testcase 15: 56 | EXPLAIN VERBOSE 57 | SELECT id, a, char_length(b) FROM delete_test; 58 | --Testcase 16: 59 | SELECT id, a, char_length(b) FROM delete_test; 60 | 61 | 62 | -- delete a row with a TOASTed value 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | DELETE FROM delete_test WHERE a > 25; 66 | --Testcase 18: 67 | DELETE FROM delete_test WHERE a > 25; 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | SELECT id, a, char_length(b) FROM delete_test; 72 | --Testcase 20: 73 | SELECT id, a, char_length(b) FROM delete_test; 74 | 75 | --Testcase 21: 76 | DROP FOREIGN TABLE delete_test; 77 | 78 | 79 | --Testcase 22: 80 | DROP USER MAPPING FOR public SERVER dynamodb_server; 81 | --Testcase 23: 82 | DROP EXTENSION dynamodb_fdw CASCADE; 83 | -------------------------------------------------------------------------------- /sql/15.7/extra/delete.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | --Testcase 4: 17 | CREATE FOREIGN TABLE delete_test (id SERIAL, a INT, b text) SERVER dynamodb_server OPTIONS (table_name 'delete_test', partition_key 'id'); 18 | 19 | --Testcase 5: 20 | EXPLAIN VERBOSE 21 | INSERT INTO delete_test (a) VALUES (10); 22 | --Testcase 6: 23 | INSERT INTO delete_test (a) VALUES (10); 24 | 25 | --Testcase 7: 26 | EXPLAIN VERBOSE 27 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 28 | --Testcase 8: 29 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 30 | 31 | --Testcase 9: 32 | EXPLAIN VERBOSE 33 | INSERT INTO delete_test (a) VALUES (100); 34 | --Testcase 10: 35 | INSERT INTO delete_test (a) VALUES (100); 36 | 37 | 38 | -- allow an alias to be specified for DELETE's target table 39 | --Testcase 11: 40 | EXPLAIN VERBOSE 41 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 42 | --Testcase 12: 43 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 44 | 45 | 46 | -- if an alias is specified, don't allow the original table name 47 | -- to be referenced 48 | --Testcase 13: 49 | EXPLAIN VERBOSE 50 | DELETE FROM delete_test dt WHERE dt.a > 25; 51 | 52 | --Testcase 14: 53 | DELETE FROM delete_test dt WHERE dt.a > 25; 54 | 55 | --Testcase 15: 56 | EXPLAIN VERBOSE 57 | SELECT id, a, char_length(b) FROM delete_test; 58 | --Testcase 16: 59 | SELECT id, a, char_length(b) FROM delete_test; 60 | 61 | 62 | -- delete a row with a TOASTed value 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | DELETE FROM delete_test WHERE a > 25; 66 | --Testcase 18: 67 | DELETE FROM delete_test WHERE a > 25; 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | SELECT id, a, char_length(b) FROM delete_test; 72 | --Testcase 20: 73 | SELECT id, a, char_length(b) FROM delete_test; 74 | 75 | --Testcase 21: 76 | DROP FOREIGN TABLE delete_test; 77 | 78 | 79 | --Testcase 22: 80 | DROP USER MAPPING FOR public SERVER dynamodb_server; 81 | --Testcase 23: 82 | DROP EXTENSION dynamodb_fdw CASCADE; 83 | -------------------------------------------------------------------------------- /sql/16.3/extra/delete.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | --Testcase 4: 17 | CREATE FOREIGN TABLE delete_test (id SERIAL, a INT, b text) SERVER dynamodb_server OPTIONS (table_name 'delete_test', partition_key 'id'); 18 | 19 | --Testcase 5: 20 | EXPLAIN VERBOSE 21 | INSERT INTO delete_test (a) VALUES (10); 22 | --Testcase 6: 23 | INSERT INTO delete_test (a) VALUES (10); 24 | 25 | --Testcase 7: 26 | EXPLAIN VERBOSE 27 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 28 | --Testcase 8: 29 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 30 | 31 | --Testcase 9: 32 | EXPLAIN VERBOSE 33 | INSERT INTO delete_test (a) VALUES (100); 34 | --Testcase 10: 35 | INSERT INTO delete_test (a) VALUES (100); 36 | 37 | 38 | -- allow an alias to be specified for DELETE's target table 39 | --Testcase 11: 40 | EXPLAIN VERBOSE 41 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 42 | --Testcase 12: 43 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 44 | 45 | 46 | -- if an alias is specified, don't allow the original table name 47 | -- to be referenced 48 | --Testcase 13: 49 | EXPLAIN VERBOSE 50 | DELETE FROM delete_test dt WHERE dt.a > 25; 51 | 52 | --Testcase 14: 53 | DELETE FROM delete_test dt WHERE dt.a > 25; 54 | 55 | --Testcase 15: 56 | EXPLAIN VERBOSE 57 | SELECT id, a, char_length(b) FROM delete_test; 58 | --Testcase 16: 59 | SELECT id, a, char_length(b) FROM delete_test; 60 | 61 | 62 | -- delete a row with a TOASTed value 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | DELETE FROM delete_test WHERE a > 25; 66 | --Testcase 18: 67 | DELETE FROM delete_test WHERE a > 25; 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | SELECT id, a, char_length(b) FROM delete_test; 72 | --Testcase 20: 73 | SELECT id, a, char_length(b) FROM delete_test; 74 | 75 | --Testcase 21: 76 | DROP FOREIGN TABLE delete_test; 77 | 78 | 79 | --Testcase 22: 80 | DROP USER MAPPING FOR public SERVER dynamodb_server; 81 | --Testcase 23: 82 | DROP EXTENSION dynamodb_fdw CASCADE; 83 | -------------------------------------------------------------------------------- /sql/17.0/extra/delete.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | --Testcase 4: 17 | CREATE FOREIGN TABLE delete_test (id SERIAL, a INT, b text) SERVER dynamodb_server OPTIONS (table_name 'delete_test', partition_key 'id'); 18 | 19 | --Testcase 5: 20 | EXPLAIN VERBOSE 21 | INSERT INTO delete_test (a) VALUES (10); 22 | --Testcase 6: 23 | INSERT INTO delete_test (a) VALUES (10); 24 | 25 | --Testcase 7: 26 | EXPLAIN VERBOSE 27 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 28 | --Testcase 8: 29 | INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); 30 | 31 | --Testcase 9: 32 | EXPLAIN VERBOSE 33 | INSERT INTO delete_test (a) VALUES (100); 34 | --Testcase 10: 35 | INSERT INTO delete_test (a) VALUES (100); 36 | 37 | 38 | -- allow an alias to be specified for DELETE's target table 39 | --Testcase 11: 40 | EXPLAIN VERBOSE 41 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 42 | --Testcase 12: 43 | DELETE FROM delete_test AS dt WHERE dt.a > 75; 44 | 45 | 46 | -- if an alias is specified, don't allow the original table name 47 | -- to be referenced 48 | --Testcase 13: 49 | EXPLAIN VERBOSE 50 | DELETE FROM delete_test dt WHERE dt.a > 25; 51 | 52 | --Testcase 14: 53 | DELETE FROM delete_test dt WHERE dt.a > 25; 54 | 55 | --Testcase 15: 56 | EXPLAIN VERBOSE 57 | SELECT id, a, char_length(b) FROM delete_test; 58 | --Testcase 16: 59 | SELECT id, a, char_length(b) FROM delete_test; 60 | 61 | 62 | -- delete a row with a TOASTed value 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | DELETE FROM delete_test WHERE a > 25; 66 | --Testcase 18: 67 | DELETE FROM delete_test WHERE a > 25; 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | SELECT id, a, char_length(b) FROM delete_test; 72 | --Testcase 20: 73 | SELECT id, a, char_length(b) FROM delete_test; 74 | 75 | --Testcase 21: 76 | DROP FOREIGN TABLE delete_test; 77 | 78 | 79 | --Testcase 22: 80 | DROP USER MAPPING FOR public SERVER dynamodb_server; 81 | --Testcase 23: 82 | DROP EXTENSION dynamodb_fdw CASCADE; 83 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DIRJANSSON = ./jansson 2 | OBJS_JANSSON = $(DIRJANSSON)/dump.o \ 3 | $(DIRJANSSON)/error.o \ 4 | $(DIRJANSSON)/hashtable.o \ 5 | $(DIRJANSSON)/hashtable_seed.o \ 6 | $(DIRJANSSON)/load.o \ 7 | $(DIRJANSSON)/memory.o \ 8 | $(DIRJANSSON)/pack_unpack.o \ 9 | $(DIRJANSSON)/strbuffer.o \ 10 | $(DIRJANSSON)/strconv.o \ 11 | $(DIRJANSSON)/utf.o \ 12 | $(DIRJANSSON)/value.o 13 | 14 | JANSSON_CFLAGS = -DHAVE_STDINT_H=1 -Wno-suggest-attribute=format 15 | 16 | MODULE_big = dynamodb_fdw 17 | OBJS = $(OBJS_JANSSON) shippable.o deparse.o dynamodb_query.o dynamodb_impl.o dynamodb_fdw.o connection.o option.o 18 | 19 | PGFILEDESC = "dynamodb_fdw - foreign data wrapper for DynamoDB" 20 | 21 | SHLIB_LINK = -lm -lstdc++ -laws-cpp-sdk-core -laws-cpp-sdk-dynamodb 22 | 23 | EXTENSION = dynamodb_fdw 24 | DATA = dynamodb_fdw--1.0.sql dynamodb_fdw--1.0--1.1.sql 25 | 26 | REGRESS = server_options connection_validation dynamodb_fdw pushdown extra/delete extra/insert extra/json extra/jsonb extra/select extra/update 27 | 28 | # EXTRA_CLEAN = sql/parquet_fdw.sql expected/parquet_fdw.out 29 | 30 | # dynamodb_impl.cpp requires C++ 11. 31 | PG_CFLAGS += -I$(DIRJANSSON) $(JANSSON_CFLAGS) 32 | PG_CXXFLAGS += -I$(DIRJANSSON) $(JANSSON_CFLAGS) -std=c++11 33 | # override PG_CXXFLAGS and PG_CFLAGS 34 | ifdef CCFLAGS 35 | override PG_CXXFLAGS += $(CCFLAGS) 36 | override PG_CFLAGS += $(CCFLAGS) 37 | endif 38 | 39 | ifdef USE_PGXS 40 | PG_CONFIG = pg_config 41 | PGXS := $(shell $(PG_CONFIG) --pgxs) 42 | include $(PGXS) 43 | else 44 | subdir = contrib/dynamodb_fdw 45 | top_builddir = ../.. 46 | 47 | # PostgreSQL uses link time optimization option which may break compilation 48 | # (this happens on travis-ci). Redefine COMPILE.cxx.bc without this option. 49 | COMPILE.cxx.bc = $(CLANG) -xc++ -Wno-ignored-attributes $(BITCODE_CXXFLAGS) $(CPPFLAGS) -emit-llvm -c 50 | 51 | include $(top_builddir)/src/Makefile.global 52 | include $(top_srcdir)/contrib/contrib-global.mk 53 | 54 | # A hurdle to use common compiler flags when building bytecode from C++ 55 | # files. should be not unnecessary, but src/Makefile.global omits passing those 56 | # flags for an unnknown reason. 57 | %.bc : %.cpp 58 | $(COMPILE.cxx.bc) $(CXXFLAGS) $(CPPFLAGS) -o $@ $< 59 | endif 60 | 61 | ifdef REGRESS_PREFIX 62 | REGRESS_PREFIX_SUB = $(REGRESS_PREFIX) 63 | else 64 | REGRESS_PREFIX_SUB = $(VERSION) 65 | endif 66 | 67 | REGRESS := $(addprefix $(REGRESS_PREFIX_SUB)/,$(REGRESS)) 68 | $(shell mkdir -p results/$(REGRESS_PREFIX_SUB)/extra) 69 | -------------------------------------------------------------------------------- /jansson/strbuffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef _GNU_SOURCE 9 | #define _GNU_SOURCE 10 | #endif 11 | 12 | #include 13 | #include 14 | #include "jansson_private.h" 15 | #include "strbuffer.h" 16 | 17 | #define STRBUFFER_MIN_SIZE 16 18 | #define STRBUFFER_FACTOR 2 19 | #define STRBUFFER_SIZE_MAX ((size_t)-1) 20 | 21 | int strbuffer_init(strbuffer_t *strbuff) 22 | { 23 | strbuff->size = STRBUFFER_MIN_SIZE; 24 | strbuff->length = 0; 25 | 26 | strbuff->value = jsonp_malloc(strbuff->size); 27 | if(!strbuff->value) 28 | return -1; 29 | 30 | /* initialize to empty */ 31 | strbuff->value[0] = '\0'; 32 | return 0; 33 | } 34 | 35 | void strbuffer_close(strbuffer_t *strbuff) 36 | { 37 | if(strbuff->value) 38 | jsonp_free(strbuff->value); 39 | 40 | strbuff->size = 0; 41 | strbuff->length = 0; 42 | strbuff->value = NULL; 43 | } 44 | 45 | void strbuffer_clear(strbuffer_t *strbuff) 46 | { 47 | strbuff->length = 0; 48 | strbuff->value[0] = '\0'; 49 | } 50 | 51 | const char *strbuffer_value(const strbuffer_t *strbuff) 52 | { 53 | return strbuff->value; 54 | } 55 | 56 | char *strbuffer_steal_value(strbuffer_t *strbuff) 57 | { 58 | char *result = strbuff->value; 59 | strbuff->value = NULL; 60 | return result; 61 | } 62 | 63 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte) 64 | { 65 | return strbuffer_append_bytes(strbuff, &byte, 1); 66 | } 67 | 68 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size) 69 | { 70 | if(size >= strbuff->size - strbuff->length) 71 | { 72 | size_t new_size; 73 | char *new_value; 74 | 75 | /* avoid integer overflow */ 76 | if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR 77 | || size > STRBUFFER_SIZE_MAX - 1 78 | || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size) 79 | return -1; 80 | 81 | new_size = max(strbuff->size * STRBUFFER_FACTOR, 82 | strbuff->length + size + 1); 83 | 84 | new_value = jsonp_malloc(new_size); 85 | if(!new_value) 86 | return -1; 87 | 88 | memcpy(new_value, strbuff->value, strbuff->length); 89 | 90 | jsonp_free(strbuff->value); 91 | strbuff->value = new_value; 92 | strbuff->size = new_size; 93 | } 94 | 95 | memcpy(strbuff->value + strbuff->length, data, size); 96 | strbuff->length += size; 97 | strbuff->value[strbuff->length] = '\0'; 98 | 99 | return 0; 100 | } 101 | 102 | char strbuffer_pop(strbuffer_t *strbuff) 103 | { 104 | if(strbuff->length > 0) { 105 | char c = strbuff->value[--strbuff->length]; 106 | strbuff->value[strbuff->length] = '\0'; 107 | return c; 108 | } 109 | else 110 | return '\0'; 111 | } 112 | -------------------------------------------------------------------------------- /expected/13.15/server_options.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | --Testcase 3: 8 | CREATE USER MAPPING FOR public SERVER dynamodb_server 9 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 10 | -- Validate extension, server and mapping details 11 | --Testcase 4: 12 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 13 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 14 | WHERE e.fdwname = 'dynamodb_fdw' 15 | ORDER BY 1, 2, 3, 4; 16 | Extension | Server | Server_Options | User_Mapping_Options 17 | --------------+-----------------+----------------------------------+--------------------------------- 18 | dynamodb_fdw | dynamodb_server | {endpoint=http://localhost:8000} | {user=admin,password=testadmin} 19 | (1 row) 20 | 21 | -- Create foreign tables and perform basic SQL operations 22 | --Testcase 5: 23 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 24 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 25 | --Testcase 6: 26 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 27 | artist | songtitle | albumtitle 28 | -----------------+---------------------+------------------ 29 | Acme Band | Happy Day | Songs About Life 30 | No One You Know | Call Me Today | Somewhat Famous 31 | No One You Know | Scared of My Shadow | Blue Sky Blues 32 | (3 rows) 33 | 34 | --Testcase 7: 35 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 36 | --Testcase 8: 37 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 38 | artist | songtitle | albumtitle 39 | -----------------+---------------------+------------------ 40 | 0000 | nOBodY LiKE mE | RECORD INSERTED 41 | Acme Band | Happy Day | Songs About Life 42 | No One You Know | Call Me Today | Somewhat Famous 43 | No One You Know | Scared of My Shadow | Blue Sky Blues 44 | (4 rows) 45 | 46 | --Testcase 9: 47 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 48 | --Testcase 10: 49 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 50 | artist | songtitle | albumtitle 51 | -----------------+---------------------+------------------ 52 | 0000 | nOBodY LiKE mE | RECORD UPDATED 53 | Acme Band | Happy Day | Songs About Life 54 | No One You Know | Call Me Today | Somewhat Famous 55 | No One You Know | Scared of My Shadow | Blue Sky Blues 56 | (4 rows) 57 | 58 | --Testcase 11: 59 | DELETE FROM server_option_tbl WHERE artist = '0000'; 60 | --Testcase 12: 61 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 62 | artist | songtitle | albumtitle 63 | -----------------+---------------------+------------------ 64 | Acme Band | Happy Day | Songs About Life 65 | No One You Know | Call Me Today | Somewhat Famous 66 | No One You Know | Scared of My Shadow | Blue Sky Blues 67 | (3 rows) 68 | 69 | -- Cleanup 70 | --Testcase 13: 71 | DROP FOREIGN TABLE server_option_tbl; 72 | --Testcase 14: 73 | DROP USER MAPPING FOR public SERVER dynamodb_server; 74 | --Testcase 15: 75 | DROP SERVER dynamodb_server; 76 | --Testcase 16: 77 | DROP EXTENSION dynamodb_fdw; 78 | -------------------------------------------------------------------------------- /expected/14.12/server_options.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | --Testcase 3: 8 | CREATE USER MAPPING FOR public SERVER dynamodb_server 9 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 10 | -- Validate extension, server and mapping details 11 | --Testcase 4: 12 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 13 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 14 | WHERE e.fdwname = 'dynamodb_fdw' 15 | ORDER BY 1, 2, 3, 4; 16 | Extension | Server | Server_Options | User_Mapping_Options 17 | --------------+-----------------+----------------------------------+--------------------------------- 18 | dynamodb_fdw | dynamodb_server | {endpoint=http://localhost:8000} | {user=admin,password=testadmin} 19 | (1 row) 20 | 21 | -- Create foreign tables and perform basic SQL operations 22 | --Testcase 5: 23 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 24 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 25 | --Testcase 6: 26 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 27 | artist | songtitle | albumtitle 28 | -----------------+---------------------+------------------ 29 | Acme Band | Happy Day | Songs About Life 30 | No One You Know | Call Me Today | Somewhat Famous 31 | No One You Know | Scared of My Shadow | Blue Sky Blues 32 | (3 rows) 33 | 34 | --Testcase 7: 35 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 36 | --Testcase 8: 37 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 38 | artist | songtitle | albumtitle 39 | -----------------+---------------------+------------------ 40 | 0000 | nOBodY LiKE mE | RECORD INSERTED 41 | Acme Band | Happy Day | Songs About Life 42 | No One You Know | Call Me Today | Somewhat Famous 43 | No One You Know | Scared of My Shadow | Blue Sky Blues 44 | (4 rows) 45 | 46 | --Testcase 9: 47 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 48 | --Testcase 10: 49 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 50 | artist | songtitle | albumtitle 51 | -----------------+---------------------+------------------ 52 | 0000 | nOBodY LiKE mE | RECORD UPDATED 53 | Acme Band | Happy Day | Songs About Life 54 | No One You Know | Call Me Today | Somewhat Famous 55 | No One You Know | Scared of My Shadow | Blue Sky Blues 56 | (4 rows) 57 | 58 | --Testcase 11: 59 | DELETE FROM server_option_tbl WHERE artist = '0000'; 60 | --Testcase 12: 61 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 62 | artist | songtitle | albumtitle 63 | -----------------+---------------------+------------------ 64 | Acme Band | Happy Day | Songs About Life 65 | No One You Know | Call Me Today | Somewhat Famous 66 | No One You Know | Scared of My Shadow | Blue Sky Blues 67 | (3 rows) 68 | 69 | -- Cleanup 70 | --Testcase 13: 71 | DROP FOREIGN TABLE server_option_tbl; 72 | --Testcase 14: 73 | DROP USER MAPPING FOR public SERVER dynamodb_server; 74 | --Testcase 15: 75 | DROP SERVER dynamodb_server; 76 | --Testcase 16: 77 | DROP EXTENSION dynamodb_fdw; 78 | -------------------------------------------------------------------------------- /expected/15.7/server_options.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | --Testcase 3: 8 | CREATE USER MAPPING FOR public SERVER dynamodb_server 9 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 10 | -- Validate extension, server and mapping details 11 | --Testcase 4: 12 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 13 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 14 | WHERE e.fdwname = 'dynamodb_fdw' 15 | ORDER BY 1, 2, 3, 4; 16 | Extension | Server | Server_Options | User_Mapping_Options 17 | --------------+-----------------+----------------------------------+--------------------------------- 18 | dynamodb_fdw | dynamodb_server | {endpoint=http://localhost:8000} | {user=admin,password=testadmin} 19 | (1 row) 20 | 21 | -- Create foreign tables and perform basic SQL operations 22 | --Testcase 5: 23 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 24 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 25 | --Testcase 6: 26 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 27 | artist | songtitle | albumtitle 28 | -----------------+---------------------+------------------ 29 | Acme Band | Happy Day | Songs About Life 30 | No One You Know | Call Me Today | Somewhat Famous 31 | No One You Know | Scared of My Shadow | Blue Sky Blues 32 | (3 rows) 33 | 34 | --Testcase 7: 35 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 36 | --Testcase 8: 37 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 38 | artist | songtitle | albumtitle 39 | -----------------+---------------------+------------------ 40 | 0000 | nOBodY LiKE mE | RECORD INSERTED 41 | Acme Band | Happy Day | Songs About Life 42 | No One You Know | Call Me Today | Somewhat Famous 43 | No One You Know | Scared of My Shadow | Blue Sky Blues 44 | (4 rows) 45 | 46 | --Testcase 9: 47 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 48 | --Testcase 10: 49 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 50 | artist | songtitle | albumtitle 51 | -----------------+---------------------+------------------ 52 | 0000 | nOBodY LiKE mE | RECORD UPDATED 53 | Acme Band | Happy Day | Songs About Life 54 | No One You Know | Call Me Today | Somewhat Famous 55 | No One You Know | Scared of My Shadow | Blue Sky Blues 56 | (4 rows) 57 | 58 | --Testcase 11: 59 | DELETE FROM server_option_tbl WHERE artist = '0000'; 60 | --Testcase 12: 61 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 62 | artist | songtitle | albumtitle 63 | -----------------+---------------------+------------------ 64 | Acme Band | Happy Day | Songs About Life 65 | No One You Know | Call Me Today | Somewhat Famous 66 | No One You Know | Scared of My Shadow | Blue Sky Blues 67 | (3 rows) 68 | 69 | -- Cleanup 70 | --Testcase 13: 71 | DROP FOREIGN TABLE server_option_tbl; 72 | --Testcase 14: 73 | DROP USER MAPPING FOR public SERVER dynamodb_server; 74 | --Testcase 15: 75 | DROP SERVER dynamodb_server; 76 | --Testcase 16: 77 | DROP EXTENSION dynamodb_fdw; 78 | -------------------------------------------------------------------------------- /expected/16.3/server_options.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | --Testcase 3: 8 | CREATE USER MAPPING FOR public SERVER dynamodb_server 9 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 10 | -- Validate extension, server and mapping details 11 | --Testcase 4: 12 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 13 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 14 | WHERE e.fdwname = 'dynamodb_fdw' 15 | ORDER BY 1, 2, 3, 4; 16 | Extension | Server | Server_Options | User_Mapping_Options 17 | --------------+-----------------+----------------------------------+--------------------------------- 18 | dynamodb_fdw | dynamodb_server | {endpoint=http://localhost:8000} | {user=admin,password=testadmin} 19 | (1 row) 20 | 21 | -- Create foreign tables and perform basic SQL operations 22 | --Testcase 5: 23 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 24 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 25 | --Testcase 6: 26 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 27 | artist | songtitle | albumtitle 28 | -----------------+---------------------+------------------ 29 | Acme Band | Happy Day | Songs About Life 30 | No One You Know | Call Me Today | Somewhat Famous 31 | No One You Know | Scared of My Shadow | Blue Sky Blues 32 | (3 rows) 33 | 34 | --Testcase 7: 35 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 36 | --Testcase 8: 37 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 38 | artist | songtitle | albumtitle 39 | -----------------+---------------------+------------------ 40 | 0000 | nOBodY LiKE mE | RECORD INSERTED 41 | Acme Band | Happy Day | Songs About Life 42 | No One You Know | Call Me Today | Somewhat Famous 43 | No One You Know | Scared of My Shadow | Blue Sky Blues 44 | (4 rows) 45 | 46 | --Testcase 9: 47 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 48 | --Testcase 10: 49 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 50 | artist | songtitle | albumtitle 51 | -----------------+---------------------+------------------ 52 | 0000 | nOBodY LiKE mE | RECORD UPDATED 53 | Acme Band | Happy Day | Songs About Life 54 | No One You Know | Call Me Today | Somewhat Famous 55 | No One You Know | Scared of My Shadow | Blue Sky Blues 56 | (4 rows) 57 | 58 | --Testcase 11: 59 | DELETE FROM server_option_tbl WHERE artist = '0000'; 60 | --Testcase 12: 61 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 62 | artist | songtitle | albumtitle 63 | -----------------+---------------------+------------------ 64 | Acme Band | Happy Day | Songs About Life 65 | No One You Know | Call Me Today | Somewhat Famous 66 | No One You Know | Scared of My Shadow | Blue Sky Blues 67 | (3 rows) 68 | 69 | -- Cleanup 70 | --Testcase 13: 71 | DROP FOREIGN TABLE server_option_tbl; 72 | --Testcase 14: 73 | DROP USER MAPPING FOR public SERVER dynamodb_server; 74 | --Testcase 15: 75 | DROP SERVER dynamodb_server; 76 | --Testcase 16: 77 | DROP EXTENSION dynamodb_fdw; 78 | -------------------------------------------------------------------------------- /expected/17.0/server_options.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | --Testcase 3: 8 | CREATE USER MAPPING FOR public SERVER dynamodb_server 9 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 10 | -- Validate extension, server and mapping details 11 | --Testcase 4: 12 | SELECT e.fdwname AS "Extension", srvname AS "Server", s.srvoptions AS "Server_Options", u.umoptions AS "User_Mapping_Options" 13 | FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver 14 | WHERE e.fdwname = 'dynamodb_fdw' 15 | ORDER BY 1, 2, 3, 4; 16 | Extension | Server | Server_Options | User_Mapping_Options 17 | --------------+-----------------+----------------------------------+--------------------------------- 18 | dynamodb_fdw | dynamodb_server | {endpoint=http://localhost:8000} | {user=admin,password=testadmin} 19 | (1 row) 20 | 21 | -- Create foreign tables and perform basic SQL operations 22 | --Testcase 5: 23 | CREATE FOREIGN TABLE server_option_tbl (artist text, songtitle text, albumtitle text) 24 | SERVER dynamodb_server OPTIONS (table_name 'server_option_tbl', partition_key 'artist', sort_key 'songtitle'); 25 | --Testcase 6: 26 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 27 | artist | songtitle | albumtitle 28 | -----------------+---------------------+------------------ 29 | Acme Band | Happy Day | Songs About Life 30 | No One You Know | Call Me Today | Somewhat Famous 31 | No One You Know | Scared of My Shadow | Blue Sky Blues 32 | (3 rows) 33 | 34 | --Testcase 7: 35 | INSERT INTO server_option_tbl VALUES ('0000', 'nOBodY LiKE mE', 'RECORD INSERTED'); 36 | --Testcase 8: 37 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 38 | artist | songtitle | albumtitle 39 | -----------------+---------------------+------------------ 40 | 0000 | nOBodY LiKE mE | RECORD INSERTED 41 | Acme Band | Happy Day | Songs About Life 42 | No One You Know | Call Me Today | Somewhat Famous 43 | No One You Know | Scared of My Shadow | Blue Sky Blues 44 | (4 rows) 45 | 46 | --Testcase 9: 47 | UPDATE server_option_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '0000'; 48 | --Testcase 10: 49 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 50 | artist | songtitle | albumtitle 51 | -----------------+---------------------+------------------ 52 | 0000 | nOBodY LiKE mE | RECORD UPDATED 53 | Acme Band | Happy Day | Songs About Life 54 | No One You Know | Call Me Today | Somewhat Famous 55 | No One You Know | Scared of My Shadow | Blue Sky Blues 56 | (4 rows) 57 | 58 | --Testcase 11: 59 | DELETE FROM server_option_tbl WHERE artist = '0000'; 60 | --Testcase 12: 61 | SELECT artist, songtitle, albumtitle FROM server_option_tbl ORDER BY 1, 2; 62 | artist | songtitle | albumtitle 63 | -----------------+---------------------+------------------ 64 | Acme Band | Happy Day | Songs About Life 65 | No One You Know | Call Me Today | Somewhat Famous 66 | No One You Know | Scared of My Shadow | Blue Sky Blues 67 | (3 rows) 68 | 69 | -- Cleanup 70 | --Testcase 13: 71 | DROP FOREIGN TABLE server_option_tbl; 72 | --Testcase 14: 73 | DROP USER MAPPING FOR public SERVER dynamodb_server; 74 | --Testcase 15: 75 | DROP SERVER dynamodb_server; 76 | --Testcase 16: 77 | DROP EXTENSION dynamodb_fdw; 78 | -------------------------------------------------------------------------------- /jansson/jansson_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef JANSSON_PRIVATE_H 9 | #define JANSSON_PRIVATE_H 10 | 11 | #include "jansson_private_config.h" 12 | #include 13 | #include "jansson.h" 14 | #include "hashtable.h" 15 | #include "strbuffer.h" 16 | 17 | #define container_of(ptr_, type_, member_) \ 18 | ((type_ *)((char *)ptr_ - offsetof(type_, member_))) 19 | 20 | /* On some platforms, max() may already be defined */ 21 | #ifndef max 22 | #define max(a, b) ((a) > (b) ? (a) : (b)) 23 | #endif 24 | 25 | /* va_copy is a C99 feature. In C89 implementations, it's sometimes 26 | available as __va_copy. If not, memcpy() should do the trick. */ 27 | #ifndef va_copy 28 | #ifdef __va_copy 29 | #define va_copy __va_copy 30 | #else 31 | #define va_copy(a, b) memcpy(&(a), &(b), sizeof(va_list)) 32 | #endif 33 | #endif 34 | 35 | typedef struct { 36 | json_t json; 37 | hashtable_t hashtable; 38 | } json_object_t; 39 | 40 | typedef struct { 41 | json_t json; 42 | size_t size; 43 | size_t entries; 44 | json_t **table; 45 | } json_array_t; 46 | 47 | typedef struct { 48 | json_t json; 49 | char *value; 50 | size_t length; 51 | } json_string_t; 52 | 53 | typedef struct { 54 | json_t json; 55 | double value; 56 | } json_real_t; 57 | 58 | typedef struct { 59 | json_t json; 60 | json_int_t value; 61 | } json_integer_t; 62 | 63 | #define json_to_object(json_) container_of(json_, json_object_t, json) 64 | #define json_to_array(json_) container_of(json_, json_array_t, json) 65 | #define json_to_string(json_) container_of(json_, json_string_t, json) 66 | #define json_to_real(json_) container_of(json_, json_real_t, json) 67 | #define json_to_integer(json_) container_of(json_, json_integer_t, json) 68 | 69 | /* Create a string by taking ownership of an existing buffer */ 70 | json_t *jsonp_stringn_nocheck_own(const char *value, size_t len); 71 | 72 | /* Error message formatting */ 73 | void jsonp_error_init(json_error_t *error, const char *source); 74 | void jsonp_error_set_source(json_error_t *error, const char *source); 75 | void jsonp_error_set(json_error_t *error, int line, int column, 76 | size_t position, enum json_error_code code, 77 | const char *msg, ...); 78 | void jsonp_error_vset(json_error_t *error, int line, int column, 79 | size_t position, enum json_error_code code, 80 | const char *msg, va_list ap); 81 | 82 | /* Locale independent string<->double conversions */ 83 | int jsonp_strtod(strbuffer_t *strbuffer, double *out); 84 | int jsonp_dtostr(char *buffer, size_t size, double value, int prec); 85 | 86 | /* Wrappers for custom memory functions */ 87 | void* jsonp_malloc(size_t size) JANSSON_ATTRS(warn_unused_result); 88 | void jsonp_free(void *ptr); 89 | char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS(warn_unused_result); 90 | char *jsonp_strdup(const char *str) JANSSON_ATTRS(warn_unused_result); 91 | char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS(warn_unused_result); 92 | 93 | 94 | /* Windows compatibility */ 95 | #if defined(_WIN32) || defined(WIN32) 96 | # if defined(_MSC_VER) /* MS compiller */ 97 | # if (_MSC_VER < 1900) && !defined(snprintf) /* snprintf not defined yet & not introduced */ 98 | # define snprintf _snprintf 99 | # endif 100 | # if (_MSC_VER < 1500) && !defined(vsnprintf) /* vsnprintf not defined yet & not introduced */ 101 | # define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a) 102 | # endif 103 | # else /* Other Windows compiller, old definition */ 104 | # define snprintf _snprintf 105 | # define vsnprintf _vsnprintf 106 | # endif 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /jansson/strconv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #ifdef __MINGW32__ 7 | #undef __NO_ISOCEXT /* ensure stdlib.h will declare prototypes for mingw own 'strtod' replacement, called '__strtod' */ 8 | #endif 9 | #include "jansson_private.h" 10 | #include "strbuffer.h" 11 | 12 | /* need jansson_private_config.h to get the correct snprintf */ 13 | #ifdef HAVE_CONFIG_H 14 | #include 15 | #endif 16 | 17 | #ifdef __MINGW32__ 18 | #define strtod __strtod 19 | #endif 20 | 21 | #if JSON_HAVE_LOCALECONV 22 | #include 23 | 24 | /* 25 | - This code assumes that the decimal separator is exactly one 26 | character. 27 | 28 | - If setlocale() is called by another thread between the call to 29 | localeconv() and the call to sprintf() or strtod(), the result may 30 | be wrong. setlocale() is not thread-safe and should not be used 31 | this way. Multi-threaded programs should use uselocale() instead. 32 | */ 33 | 34 | static void to_locale(strbuffer_t *strbuffer) 35 | { 36 | const char *point; 37 | char *pos; 38 | 39 | point = localeconv()->decimal_point; 40 | if(*point == '.') { 41 | /* No conversion needed */ 42 | return; 43 | } 44 | 45 | pos = strchr(strbuffer->value, '.'); 46 | if(pos) 47 | *pos = *point; 48 | } 49 | 50 | static void from_locale(char *buffer) 51 | { 52 | const char *point; 53 | char *pos; 54 | 55 | point = localeconv()->decimal_point; 56 | if(*point == '.') { 57 | /* No conversion needed */ 58 | return; 59 | } 60 | 61 | pos = strchr(buffer, *point); 62 | if(pos) 63 | *pos = '.'; 64 | } 65 | #endif 66 | 67 | int jsonp_strtod(strbuffer_t *strbuffer, double *out) 68 | { 69 | double value; 70 | char *end; 71 | 72 | #if JSON_HAVE_LOCALECONV 73 | to_locale(strbuffer); 74 | #endif 75 | 76 | errno = 0; 77 | value = strtod(strbuffer->value, &end); 78 | assert(end == strbuffer->value + strbuffer->length); 79 | 80 | if((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) { 81 | /* Overflow */ 82 | return -1; 83 | } 84 | 85 | *out = value; 86 | return 0; 87 | } 88 | 89 | int jsonp_dtostr(char *buffer, size_t size, double value, int precision) 90 | { 91 | int ret; 92 | char *start, *end; 93 | size_t length; 94 | 95 | if (precision == 0) 96 | precision = 17; 97 | 98 | ret = snprintf(buffer, size, "%.*g", precision, value); 99 | if(ret < 0) 100 | return -1; 101 | 102 | length = (size_t)ret; 103 | if(length >= size) 104 | return -1; 105 | 106 | #if JSON_HAVE_LOCALECONV 107 | from_locale(buffer); 108 | #endif 109 | 110 | /* Make sure there's a dot or 'e' in the output. Otherwise 111 | a real is converted to an integer when decoding */ 112 | if(strchr(buffer, '.') == NULL && 113 | strchr(buffer, 'e') == NULL) 114 | { 115 | if(length + 3 >= size) { 116 | /* No space to append ".0" */ 117 | return -1; 118 | } 119 | buffer[length] = '.'; 120 | buffer[length + 1] = '0'; 121 | buffer[length + 2] = '\0'; 122 | length += 2; 123 | } 124 | 125 | /* Remove leading '+' from positive exponent. Also remove leading 126 | zeros from exponents (added by some printf() implementations) */ 127 | start = strchr(buffer, 'e'); 128 | if(start) { 129 | start++; 130 | end = start + 1; 131 | 132 | if(*start == '-') 133 | start++; 134 | 135 | while(*end == '0') 136 | end++; 137 | 138 | if(end != start) { 139 | memmove(start, end, length - (size_t)(end - buffer)); 140 | length -= (size_t)(end - start); 141 | } 142 | } 143 | 144 | return (int)length; 145 | } 146 | -------------------------------------------------------------------------------- /sql/13.15/extra/insert.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- 17 | -- insert with DEFAULT in the target_list 18 | -- 19 | --Testcase 4: 20 | CREATE FOREIGN TABLE inserttest ("ID" int, col1 int4, col2 int4, col3 text) 21 | SERVER dynamodb_server OPTIONS (table_name 'inserttest', partition_key 'ID'); 22 | 23 | --Testcase 5: 24 | EXPLAIN VERBOSE 25 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 26 | --Testcase 6: 27 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 28 | 29 | --Testcase 7: 30 | EXPLAIN VERBOSE 31 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 32 | --Testcase 8: 33 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 34 | 35 | --Testcase 9: 36 | EXPLAIN VERBOSE 37 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 38 | --Testcase 10: 39 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 40 | 41 | --Testcase 11: 42 | EXPLAIN VERBOSE 43 | insert into inserttest values (4, DEFAULT, 5, 'test'); 44 | --Testcase 12: 45 | insert into inserttest values (4, DEFAULT, 5, 'test'); 46 | 47 | --Testcase 13: 48 | EXPLAIN VERBOSE 49 | insert into inserttest values (5, DEFAULT, 7); 50 | --Testcase 14: 51 | insert into inserttest values (5, DEFAULT, 7); 52 | 53 | --Testcase 15: 54 | EXPLAIN VERBOSE 55 | select * from inserttest; 56 | --Testcase 16: 57 | select * from inserttest; 58 | 59 | 60 | -- 61 | -- insert with similar expression / target_list values (all fail) 62 | -- 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 66 | --Testcase 18: 67 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 72 | --Testcase 20: 73 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 74 | 75 | --Testcase 21: 76 | EXPLAIN VERBOSE 77 | insert into inserttest ("ID", col1) values (8, 1, 2); 78 | --Testcase 22: 79 | insert into inserttest ("ID", col1) values (8, 1, 2); 80 | 81 | --Testcase 23: 82 | EXPLAIN VERBOSE 83 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 84 | --Testcase 24: 85 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 86 | 87 | --Testcase 25: 88 | select * from inserttest; 89 | 90 | -- 91 | -- VALUES test 92 | -- 93 | --Testcase 26: 94 | EXPLAIN VERBOSE 95 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 96 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 97 | 98 | --Testcase 27: 99 | EXPLAIN VERBOSE 100 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 101 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 102 | 103 | --Testcase 28: 104 | select * from inserttest; 105 | 106 | -- 107 | -- TOASTed value test 108 | -- 109 | --Testcase 29: 110 | EXPLAIN VERBOSE 111 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 112 | --Testcase 30: 113 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 114 | 115 | --Testcase 31: 116 | EXPLAIN VERBOSE 117 | select col1, col2, char_length(col3) from inserttest; 118 | --Testcase 32: 119 | select col1, col2, char_length(col3) from inserttest; 120 | 121 | 122 | --Testcase 33: 123 | drop foreign table inserttest; 124 | 125 | --Testcase 34: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 35: 128 | DROP EXTENSION dynamodb_fdw CASCADE; 129 | -------------------------------------------------------------------------------- /sql/14.12/extra/insert.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- 17 | -- insert with DEFAULT in the target_list 18 | -- 19 | --Testcase 4: 20 | CREATE FOREIGN TABLE inserttest ("ID" int, col1 int4, col2 int4, col3 text) 21 | SERVER dynamodb_server OPTIONS (table_name 'inserttest', partition_key 'ID'); 22 | 23 | --Testcase 5: 24 | EXPLAIN VERBOSE 25 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 26 | --Testcase 6: 27 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 28 | 29 | --Testcase 7: 30 | EXPLAIN VERBOSE 31 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 32 | --Testcase 8: 33 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 34 | 35 | --Testcase 9: 36 | EXPLAIN VERBOSE 37 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 38 | --Testcase 10: 39 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 40 | 41 | --Testcase 11: 42 | EXPLAIN VERBOSE 43 | insert into inserttest values (4, DEFAULT, 5, 'test'); 44 | --Testcase 12: 45 | insert into inserttest values (4, DEFAULT, 5, 'test'); 46 | 47 | --Testcase 13: 48 | EXPLAIN VERBOSE 49 | insert into inserttest values (5, DEFAULT, 7); 50 | --Testcase 14: 51 | insert into inserttest values (5, DEFAULT, 7); 52 | 53 | --Testcase 15: 54 | EXPLAIN VERBOSE 55 | select * from inserttest; 56 | --Testcase 16: 57 | select * from inserttest; 58 | 59 | 60 | -- 61 | -- insert with similar expression / target_list values (all fail) 62 | -- 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 66 | --Testcase 18: 67 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 72 | --Testcase 20: 73 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 74 | 75 | --Testcase 21: 76 | EXPLAIN VERBOSE 77 | insert into inserttest ("ID", col1) values (8, 1, 2); 78 | --Testcase 22: 79 | insert into inserttest ("ID", col1) values (8, 1, 2); 80 | 81 | --Testcase 23: 82 | EXPLAIN VERBOSE 83 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 84 | --Testcase 24: 85 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 86 | 87 | --Testcase 25: 88 | select * from inserttest; 89 | 90 | -- 91 | -- VALUES test 92 | -- 93 | --Testcase 26: 94 | EXPLAIN VERBOSE 95 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 96 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 97 | 98 | --Testcase 27: 99 | EXPLAIN VERBOSE 100 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 101 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 102 | 103 | --Testcase 28: 104 | select * from inserttest; 105 | 106 | -- 107 | -- TOASTed value test 108 | -- 109 | --Testcase 29: 110 | EXPLAIN VERBOSE 111 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 112 | --Testcase 30: 113 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 114 | 115 | --Testcase 31: 116 | EXPLAIN VERBOSE 117 | select col1, col2, char_length(col3) from inserttest; 118 | --Testcase 32: 119 | select col1, col2, char_length(col3) from inserttest; 120 | 121 | 122 | --Testcase 33: 123 | drop foreign table inserttest; 124 | 125 | --Testcase 34: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 35: 128 | DROP EXTENSION dynamodb_fdw CASCADE; 129 | -------------------------------------------------------------------------------- /sql/15.7/extra/insert.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- 17 | -- insert with DEFAULT in the target_list 18 | -- 19 | --Testcase 4: 20 | CREATE FOREIGN TABLE inserttest ("ID" int, col1 int4, col2 int4, col3 text) 21 | SERVER dynamodb_server OPTIONS (table_name 'inserttest', partition_key 'ID'); 22 | 23 | --Testcase 5: 24 | EXPLAIN VERBOSE 25 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 26 | --Testcase 6: 27 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 28 | 29 | --Testcase 7: 30 | EXPLAIN VERBOSE 31 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 32 | --Testcase 8: 33 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 34 | 35 | --Testcase 9: 36 | EXPLAIN VERBOSE 37 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 38 | --Testcase 10: 39 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 40 | 41 | --Testcase 11: 42 | EXPLAIN VERBOSE 43 | insert into inserttest values (4, DEFAULT, 5, 'test'); 44 | --Testcase 12: 45 | insert into inserttest values (4, DEFAULT, 5, 'test'); 46 | 47 | --Testcase 13: 48 | EXPLAIN VERBOSE 49 | insert into inserttest values (5, DEFAULT, 7); 50 | --Testcase 14: 51 | insert into inserttest values (5, DEFAULT, 7); 52 | 53 | --Testcase 15: 54 | EXPLAIN VERBOSE 55 | select * from inserttest; 56 | --Testcase 16: 57 | select * from inserttest; 58 | 59 | 60 | -- 61 | -- insert with similar expression / target_list values (all fail) 62 | -- 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 66 | --Testcase 18: 67 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 72 | --Testcase 20: 73 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 74 | 75 | --Testcase 21: 76 | EXPLAIN VERBOSE 77 | insert into inserttest ("ID", col1) values (8, 1, 2); 78 | --Testcase 22: 79 | insert into inserttest ("ID", col1) values (8, 1, 2); 80 | 81 | --Testcase 23: 82 | EXPLAIN VERBOSE 83 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 84 | --Testcase 24: 85 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 86 | 87 | --Testcase 25: 88 | select * from inserttest; 89 | 90 | -- 91 | -- VALUES test 92 | -- 93 | --Testcase 26: 94 | EXPLAIN VERBOSE 95 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 96 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 97 | 98 | --Testcase 27: 99 | EXPLAIN VERBOSE 100 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 101 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 102 | 103 | --Testcase 28: 104 | select * from inserttest; 105 | 106 | -- 107 | -- TOASTed value test 108 | -- 109 | --Testcase 29: 110 | EXPLAIN VERBOSE 111 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 112 | --Testcase 30: 113 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 114 | 115 | --Testcase 31: 116 | EXPLAIN VERBOSE 117 | select col1, col2, char_length(col3) from inserttest; 118 | --Testcase 32: 119 | select col1, col2, char_length(col3) from inserttest; 120 | 121 | 122 | --Testcase 33: 123 | drop foreign table inserttest; 124 | 125 | --Testcase 34: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 35: 128 | DROP EXTENSION dynamodb_fdw CASCADE; 129 | -------------------------------------------------------------------------------- /sql/16.3/extra/insert.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- 17 | -- insert with DEFAULT in the target_list 18 | -- 19 | --Testcase 4: 20 | CREATE FOREIGN TABLE inserttest ("ID" int, col1 int4, col2 int4, col3 text) 21 | SERVER dynamodb_server OPTIONS (table_name 'inserttest', partition_key 'ID'); 22 | 23 | --Testcase 5: 24 | EXPLAIN VERBOSE 25 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 26 | --Testcase 6: 27 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 28 | 29 | --Testcase 7: 30 | EXPLAIN VERBOSE 31 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 32 | --Testcase 8: 33 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 34 | 35 | --Testcase 9: 36 | EXPLAIN VERBOSE 37 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 38 | --Testcase 10: 39 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 40 | 41 | --Testcase 11: 42 | EXPLAIN VERBOSE 43 | insert into inserttest values (4, DEFAULT, 5, 'test'); 44 | --Testcase 12: 45 | insert into inserttest values (4, DEFAULT, 5, 'test'); 46 | 47 | --Testcase 13: 48 | EXPLAIN VERBOSE 49 | insert into inserttest values (5, DEFAULT, 7); 50 | --Testcase 14: 51 | insert into inserttest values (5, DEFAULT, 7); 52 | 53 | --Testcase 15: 54 | EXPLAIN VERBOSE 55 | select * from inserttest; 56 | --Testcase 16: 57 | select * from inserttest; 58 | 59 | 60 | -- 61 | -- insert with similar expression / target_list values (all fail) 62 | -- 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 66 | --Testcase 18: 67 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 72 | --Testcase 20: 73 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 74 | 75 | --Testcase 21: 76 | EXPLAIN VERBOSE 77 | insert into inserttest ("ID", col1) values (8, 1, 2); 78 | --Testcase 22: 79 | insert into inserttest ("ID", col1) values (8, 1, 2); 80 | 81 | --Testcase 23: 82 | EXPLAIN VERBOSE 83 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 84 | --Testcase 24: 85 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 86 | 87 | --Testcase 25: 88 | select * from inserttest; 89 | 90 | -- 91 | -- VALUES test 92 | -- 93 | --Testcase 26: 94 | EXPLAIN VERBOSE 95 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 96 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 97 | 98 | --Testcase 27: 99 | EXPLAIN VERBOSE 100 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 101 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 102 | 103 | --Testcase 28: 104 | select * from inserttest; 105 | 106 | -- 107 | -- TOASTed value test 108 | -- 109 | --Testcase 29: 110 | EXPLAIN VERBOSE 111 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 112 | --Testcase 30: 113 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 114 | 115 | --Testcase 31: 116 | EXPLAIN VERBOSE 117 | select col1, col2, char_length(col3) from inserttest; 118 | --Testcase 32: 119 | select col1, col2, char_length(col3) from inserttest; 120 | 121 | 122 | --Testcase 33: 123 | drop foreign table inserttest; 124 | 125 | --Testcase 34: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 35: 128 | DROP EXTENSION dynamodb_fdw CASCADE; 129 | -------------------------------------------------------------------------------- /sql/17.0/extra/insert.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- 17 | -- insert with DEFAULT in the target_list 18 | -- 19 | --Testcase 4: 20 | CREATE FOREIGN TABLE inserttest ("ID" int, col1 int4, col2 int4, col3 text) 21 | SERVER dynamodb_server OPTIONS (table_name 'inserttest', partition_key 'ID'); 22 | 23 | --Testcase 5: 24 | EXPLAIN VERBOSE 25 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 26 | --Testcase 6: 27 | insert into inserttest ("ID", col1, col2, col3) values (1, DEFAULT, DEFAULT, DEFAULT); 28 | 29 | --Testcase 7: 30 | EXPLAIN VERBOSE 31 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 32 | --Testcase 8: 33 | insert into inserttest ("ID", col2, col3) values (2, 3, DEFAULT); 34 | 35 | --Testcase 9: 36 | EXPLAIN VERBOSE 37 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 38 | --Testcase 10: 39 | insert into inserttest ("ID", col1, col2, col3) values (3, DEFAULT, 5, DEFAULT); 40 | 41 | --Testcase 11: 42 | EXPLAIN VERBOSE 43 | insert into inserttest values (4, DEFAULT, 5, 'test'); 44 | --Testcase 12: 45 | insert into inserttest values (4, DEFAULT, 5, 'test'); 46 | 47 | --Testcase 13: 48 | EXPLAIN VERBOSE 49 | insert into inserttest values (5, DEFAULT, 7); 50 | --Testcase 14: 51 | insert into inserttest values (5, DEFAULT, 7); 52 | 53 | --Testcase 15: 54 | EXPLAIN VERBOSE 55 | select * from inserttest; 56 | --Testcase 16: 57 | select * from inserttest; 58 | 59 | 60 | -- 61 | -- insert with similar expression / target_list values (all fail) 62 | -- 63 | --Testcase 17: 64 | EXPLAIN VERBOSE 65 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 66 | --Testcase 18: 67 | insert into inserttest ("ID", col1, col2, col3) values (6, DEFAULT, DEFAULT); 68 | 69 | --Testcase 19: 70 | EXPLAIN VERBOSE 71 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 72 | --Testcase 20: 73 | insert into inserttest ("ID", col1, col2, col3) values (7, 1, 2); 74 | 75 | --Testcase 21: 76 | EXPLAIN VERBOSE 77 | insert into inserttest ("ID", col1) values (8, 1, 2); 78 | --Testcase 22: 79 | insert into inserttest ("ID", col1) values (8, 1, 2); 80 | 81 | --Testcase 23: 82 | EXPLAIN VERBOSE 83 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 84 | --Testcase 24: 85 | insert into inserttest ("ID", col1) values (9, DEFAULT, DEFAULT); 86 | 87 | --Testcase 25: 88 | select * from inserttest; 89 | 90 | -- 91 | -- VALUES test 92 | -- 93 | --Testcase 26: 94 | EXPLAIN VERBOSE 95 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 96 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 97 | 98 | --Testcase 27: 99 | EXPLAIN VERBOSE 100 | insert into inserttest values(10, 10, 20, '40'), (11, -1, 2, DEFAULT), 101 | (11, (select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); 102 | 103 | --Testcase 28: 104 | select * from inserttest; 105 | 106 | -- 107 | -- TOASTed value test 108 | -- 109 | --Testcase 29: 110 | EXPLAIN VERBOSE 111 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 112 | --Testcase 30: 113 | insert into inserttest values(12, 30, 50, repeat('x', 10000)); 114 | 115 | --Testcase 31: 116 | EXPLAIN VERBOSE 117 | select col1, col2, char_length(col3) from inserttest; 118 | --Testcase 32: 119 | select col1, col2, char_length(col3) from inserttest; 120 | 121 | 122 | --Testcase 33: 123 | drop foreign table inserttest; 124 | 125 | --Testcase 34: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 35: 128 | DROP EXTENSION dynamodb_fdw CASCADE; 129 | -------------------------------------------------------------------------------- /sql/13.15/dynamodb_fdw.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | -- Get version 12 | --Testcase 42: 13 | SELECT * FROM public.dynamodb_fdw_version(); 14 | --Testcase 43: 15 | SELECT dynamodb_fdw_version(); 16 | -- ==================================================================== 17 | -- Check that userid to use when querying the remote table is correctly 18 | -- propagated into foreign rels. 19 | -- ==================================================================== 20 | -- create empty_owner without access information to detect incorrect UserID. 21 | --Testcase 3: 22 | CREATE ROLE empty_owner LOGIN SUPERUSER; 23 | --Testcase 4: 24 | SET ROLE empty_owner; 25 | 26 | --Testcase 5: 27 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 28 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 29 | 30 | --Testcase 6: 31 | CREATE VIEW v4 AS SELECT * FROM example1; 32 | -- If undefine user owner, postgres core defaults to using the current user to query. 33 | -- For Foreign Scan, Foreign Modify. 34 | --Testcase 7: 35 | SELECT * FROM v4; 36 | --Testcase 8: 37 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 38 | --Testcase 9: 39 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 40 | --Testcase 10: 41 | DELETE FROM v4; 42 | 43 | --Testcase 11: 44 | CREATE ROLE regress_view_owner_another; 45 | --Testcase 12: 46 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 47 | --Testcase 13: 48 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 49 | --Testcase 14: 50 | GRANT SELECT ON example1 TO regress_view_owner_another; 51 | --Testcase 15: 52 | GRANT INSERT ON example1 TO regress_view_owner_another; 53 | --Testcase 16: 54 | GRANT UPDATE ON example1 TO regress_view_owner_another; 55 | --Testcase 17: 56 | GRANT DELETE ON example1 TO regress_view_owner_another; 57 | 58 | -- It fails as expected due to the lack of a user mapping for that user. 59 | -- For Foreign Scan, Foreign Modify. 60 | --Testcase 18: 61 | SELECT * FROM v4; 62 | --Testcase 19: 63 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 64 | --Testcase 20: 65 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 66 | --Testcase 21: 67 | DELETE FROM v4; 68 | 69 | -- Identify the correct user, but it fails due to the lack access informations. 70 | --Testcase 22: 71 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 72 | -- For Foreign Scan, Foreign Modify. 73 | --Testcase 23: 74 | SELECT * FROM v4; 75 | --Testcase 24: 76 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 77 | --Testcase 25: 78 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 79 | --Testcase 26: 80 | DELETE FROM v4; 81 | 82 | --Testcase 27: 83 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 84 | 85 | -- Should not get that error once a user mapping is created and have enough information. 86 | --Testcase 28: 87 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 88 | -- For Foreign Scan, Foreign Modify. 89 | --Testcase 29: 90 | SELECT * FROM v4; 91 | --Testcase 30: 92 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 93 | --Testcase 31: 94 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 95 | --Testcase 32: 96 | DELETE FROM v4; 97 | 98 | -- Clean 99 | --Testcase 33: 100 | DROP VIEW v4; 101 | --Testcase 34: 102 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 103 | --Testcase 35: 104 | DROP OWNED BY regress_view_owner_another; 105 | --Testcase 36: 106 | DROP OWNED BY empty_owner; 107 | --Testcase 37: 108 | DROP ROLE regress_view_owner_another; 109 | --Testcase 38: 110 | -- current user cannot be dropped 111 | --Testcase 39: 112 | RESET ROLE; 113 | --Testcase 40: 114 | DROP ROLE empty_owner; 115 | --Testcase 41: 116 | DROP EXTENSION dynamodb_fdw CASCADE; 117 | -------------------------------------------------------------------------------- /sql/14.12/dynamodb_fdw.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | -- Get version 12 | --Testcase 42: 13 | SELECT * FROM public.dynamodb_fdw_version(); 14 | --Testcase 43: 15 | SELECT dynamodb_fdw_version(); 16 | -- ==================================================================== 17 | -- Check that userid to use when querying the remote table is correctly 18 | -- propagated into foreign rels. 19 | -- ==================================================================== 20 | -- create empty_owner without access information to detect incorrect UserID. 21 | --Testcase 3: 22 | CREATE ROLE empty_owner LOGIN SUPERUSER; 23 | --Testcase 4: 24 | SET ROLE empty_owner; 25 | 26 | --Testcase 5: 27 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 28 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 29 | 30 | --Testcase 6: 31 | CREATE VIEW v4 AS SELECT * FROM example1; 32 | -- If undefine user owner, postgres core defaults to using the current user to query. 33 | -- For Foreign Scan, Foreign Modify. 34 | --Testcase 7: 35 | SELECT * FROM v4; 36 | --Testcase 8: 37 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 38 | --Testcase 9: 39 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 40 | --Testcase 10: 41 | DELETE FROM v4; 42 | 43 | --Testcase 11: 44 | CREATE ROLE regress_view_owner_another; 45 | --Testcase 12: 46 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 47 | --Testcase 13: 48 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 49 | --Testcase 14: 50 | GRANT SELECT ON example1 TO regress_view_owner_another; 51 | --Testcase 15: 52 | GRANT INSERT ON example1 TO regress_view_owner_another; 53 | --Testcase 16: 54 | GRANT UPDATE ON example1 TO regress_view_owner_another; 55 | --Testcase 17: 56 | GRANT DELETE ON example1 TO regress_view_owner_another; 57 | 58 | -- It fails as expected due to the lack of a user mapping for that user. 59 | -- For Foreign Scan, Foreign Modify. 60 | --Testcase 18: 61 | SELECT * FROM v4; 62 | --Testcase 19: 63 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 64 | --Testcase 20: 65 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 66 | --Testcase 21: 67 | DELETE FROM v4; 68 | 69 | -- Identify the correct user, but it fails due to the lack access informations. 70 | --Testcase 22: 71 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 72 | -- For Foreign Scan, Foreign Modify. 73 | --Testcase 23: 74 | SELECT * FROM v4; 75 | --Testcase 24: 76 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 77 | --Testcase 25: 78 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 79 | --Testcase 26: 80 | DELETE FROM v4; 81 | 82 | --Testcase 27: 83 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 84 | 85 | -- Should not get that error once a user mapping is created and have enough information. 86 | --Testcase 28: 87 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 88 | -- For Foreign Scan, Foreign Modify. 89 | --Testcase 29: 90 | SELECT * FROM v4; 91 | --Testcase 30: 92 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 93 | --Testcase 31: 94 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 95 | --Testcase 32: 96 | DELETE FROM v4; 97 | 98 | -- Clean 99 | --Testcase 33: 100 | DROP VIEW v4; 101 | --Testcase 34: 102 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 103 | --Testcase 35: 104 | DROP OWNED BY regress_view_owner_another; 105 | --Testcase 36: 106 | DROP OWNED BY empty_owner; 107 | --Testcase 37: 108 | DROP ROLE regress_view_owner_another; 109 | --Testcase 38: 110 | -- current user cannot be dropped 111 | --Testcase 39: 112 | RESET ROLE; 113 | --Testcase 40: 114 | DROP ROLE empty_owner; 115 | --Testcase 41: 116 | DROP EXTENSION dynamodb_fdw CASCADE; 117 | -------------------------------------------------------------------------------- /sql/15.7/dynamodb_fdw.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | -- Get version 12 | --Testcase 42: 13 | SELECT * FROM public.dynamodb_fdw_version(); 14 | --Testcase 43: 15 | SELECT dynamodb_fdw_version(); 16 | -- ==================================================================== 17 | -- Check that userid to use when querying the remote table is correctly 18 | -- propagated into foreign rels. 19 | -- ==================================================================== 20 | -- create empty_owner without access information to detect incorrect UserID. 21 | --Testcase 3: 22 | CREATE ROLE empty_owner LOGIN SUPERUSER; 23 | --Testcase 4: 24 | SET ROLE empty_owner; 25 | 26 | --Testcase 5: 27 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 28 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 29 | 30 | --Testcase 6: 31 | CREATE VIEW v4 AS SELECT * FROM example1; 32 | -- If undefine user owner, postgres core defaults to using the current user to query. 33 | -- For Foreign Scan, Foreign Modify. 34 | --Testcase 7: 35 | SELECT * FROM v4; 36 | --Testcase 8: 37 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 38 | --Testcase 9: 39 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 40 | --Testcase 10: 41 | DELETE FROM v4; 42 | 43 | --Testcase 11: 44 | CREATE ROLE regress_view_owner_another; 45 | --Testcase 12: 46 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 47 | --Testcase 13: 48 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 49 | --Testcase 14: 50 | GRANT SELECT ON example1 TO regress_view_owner_another; 51 | --Testcase 15: 52 | GRANT INSERT ON example1 TO regress_view_owner_another; 53 | --Testcase 16: 54 | GRANT UPDATE ON example1 TO regress_view_owner_another; 55 | --Testcase 17: 56 | GRANT DELETE ON example1 TO regress_view_owner_another; 57 | 58 | -- It fails as expected due to the lack of a user mapping for that user. 59 | -- For Foreign Scan, Foreign Modify. 60 | --Testcase 18: 61 | SELECT * FROM v4; 62 | --Testcase 19: 63 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 64 | --Testcase 20: 65 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 66 | --Testcase 21: 67 | DELETE FROM v4; 68 | 69 | -- Identify the correct user, but it fails due to the lack access informations. 70 | --Testcase 22: 71 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 72 | -- For Foreign Scan, Foreign Modify. 73 | --Testcase 23: 74 | SELECT * FROM v4; 75 | --Testcase 24: 76 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 77 | --Testcase 25: 78 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 79 | --Testcase 26: 80 | DELETE FROM v4; 81 | 82 | --Testcase 27: 83 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 84 | 85 | -- Should not get that error once a user mapping is created and have enough information. 86 | --Testcase 28: 87 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 88 | -- For Foreign Scan, Foreign Modify. 89 | --Testcase 29: 90 | SELECT * FROM v4; 91 | --Testcase 30: 92 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 93 | --Testcase 31: 94 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 95 | --Testcase 32: 96 | DELETE FROM v4; 97 | 98 | -- Clean 99 | --Testcase 33: 100 | DROP VIEW v4; 101 | --Testcase 34: 102 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 103 | --Testcase 35: 104 | DROP OWNED BY regress_view_owner_another; 105 | --Testcase 36: 106 | DROP OWNED BY empty_owner; 107 | --Testcase 37: 108 | DROP ROLE regress_view_owner_another; 109 | --Testcase 38: 110 | -- current user cannot be dropped 111 | --Testcase 39: 112 | RESET ROLE; 113 | --Testcase 40: 114 | DROP ROLE empty_owner; 115 | --Testcase 41: 116 | DROP EXTENSION dynamodb_fdw CASCADE; 117 | -------------------------------------------------------------------------------- /sql/16.3/dynamodb_fdw.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | -- Get version 12 | --Testcase 42: 13 | SELECT * FROM public.dynamodb_fdw_version(); 14 | --Testcase 43: 15 | SELECT dynamodb_fdw_version(); 16 | -- ==================================================================== 17 | -- Check that userid to use when querying the remote table is correctly 18 | -- propagated into foreign rels. 19 | -- ==================================================================== 20 | -- create empty_owner without access information to detect incorrect UserID. 21 | --Testcase 3: 22 | CREATE ROLE empty_owner LOGIN SUPERUSER; 23 | --Testcase 4: 24 | SET ROLE empty_owner; 25 | 26 | --Testcase 5: 27 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 28 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 29 | 30 | --Testcase 6: 31 | CREATE VIEW v4 AS SELECT * FROM example1; 32 | -- If undefine user owner, postgres core defaults to using the current user to query. 33 | -- For Foreign Scan, Foreign Modify. 34 | --Testcase 7: 35 | SELECT * FROM v4; 36 | --Testcase 8: 37 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 38 | --Testcase 9: 39 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 40 | --Testcase 10: 41 | DELETE FROM v4; 42 | 43 | --Testcase 11: 44 | CREATE ROLE regress_view_owner_another; 45 | --Testcase 12: 46 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 47 | --Testcase 13: 48 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 49 | --Testcase 14: 50 | GRANT SELECT ON example1 TO regress_view_owner_another; 51 | --Testcase 15: 52 | GRANT INSERT ON example1 TO regress_view_owner_another; 53 | --Testcase 16: 54 | GRANT UPDATE ON example1 TO regress_view_owner_another; 55 | --Testcase 17: 56 | GRANT DELETE ON example1 TO regress_view_owner_another; 57 | 58 | -- It fails as expected due to the lack of a user mapping for that user. 59 | -- For Foreign Scan, Foreign Modify. 60 | --Testcase 18: 61 | SELECT * FROM v4; 62 | --Testcase 19: 63 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 64 | --Testcase 20: 65 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 66 | --Testcase 21: 67 | DELETE FROM v4; 68 | 69 | -- Identify the correct user, but it fails due to the lack access informations. 70 | --Testcase 22: 71 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 72 | -- For Foreign Scan, Foreign Modify. 73 | --Testcase 23: 74 | SELECT * FROM v4; 75 | --Testcase 24: 76 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 77 | --Testcase 25: 78 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 79 | --Testcase 26: 80 | DELETE FROM v4; 81 | 82 | --Testcase 27: 83 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 84 | 85 | -- Should not get that error once a user mapping is created and have enough information. 86 | --Testcase 28: 87 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 88 | -- For Foreign Scan, Foreign Modify. 89 | --Testcase 29: 90 | SELECT * FROM v4; 91 | --Testcase 30: 92 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 93 | --Testcase 31: 94 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 95 | --Testcase 32: 96 | DELETE FROM v4; 97 | 98 | -- Clean 99 | --Testcase 33: 100 | DROP VIEW v4; 101 | --Testcase 34: 102 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 103 | --Testcase 35: 104 | DROP OWNED BY regress_view_owner_another; 105 | --Testcase 36: 106 | DROP OWNED BY empty_owner; 107 | --Testcase 37: 108 | DROP ROLE regress_view_owner_another; 109 | --Testcase 38: 110 | -- current user cannot be dropped 111 | --Testcase 39: 112 | RESET ROLE; 113 | --Testcase 40: 114 | DROP ROLE empty_owner; 115 | --Testcase 41: 116 | DROP EXTENSION dynamodb_fdw CASCADE; 117 | -------------------------------------------------------------------------------- /sql/17.0/dynamodb_fdw.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | -- Get version 12 | --Testcase 42: 13 | SELECT * FROM public.dynamodb_fdw_version(); 14 | --Testcase 43: 15 | SELECT dynamodb_fdw_version(); 16 | -- ==================================================================== 17 | -- Check that userid to use when querying the remote table is correctly 18 | -- propagated into foreign rels. 19 | -- ==================================================================== 20 | -- create empty_owner without access information to detect incorrect UserID. 21 | --Testcase 3: 22 | CREATE ROLE empty_owner LOGIN SUPERUSER; 23 | --Testcase 4: 24 | SET ROLE empty_owner; 25 | 26 | --Testcase 5: 27 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 28 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 29 | 30 | --Testcase 6: 31 | CREATE VIEW v4 AS SELECT * FROM example1; 32 | -- If undefine user owner, postgres core defaults to using the current user to query. 33 | -- For Foreign Scan, Foreign Modify. 34 | --Testcase 7: 35 | SELECT * FROM v4; 36 | --Testcase 8: 37 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 38 | --Testcase 9: 39 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 40 | --Testcase 10: 41 | DELETE FROM v4; 42 | 43 | --Testcase 11: 44 | CREATE ROLE regress_view_owner_another; 45 | --Testcase 12: 46 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 47 | --Testcase 13: 48 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 49 | --Testcase 14: 50 | GRANT SELECT ON example1 TO regress_view_owner_another; 51 | --Testcase 15: 52 | GRANT INSERT ON example1 TO regress_view_owner_another; 53 | --Testcase 16: 54 | GRANT UPDATE ON example1 TO regress_view_owner_another; 55 | --Testcase 17: 56 | GRANT DELETE ON example1 TO regress_view_owner_another; 57 | 58 | -- It fails as expected due to the lack of a user mapping for that user. 59 | -- For Foreign Scan, Foreign Modify. 60 | --Testcase 18: 61 | SELECT * FROM v4; 62 | --Testcase 19: 63 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 64 | --Testcase 20: 65 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 66 | --Testcase 21: 67 | DELETE FROM v4; 68 | 69 | -- Identify the correct user, but it fails due to the lack access informations. 70 | --Testcase 22: 71 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 72 | -- For Foreign Scan, Foreign Modify. 73 | --Testcase 23: 74 | SELECT * FROM v4; 75 | --Testcase 24: 76 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 77 | --Testcase 25: 78 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 79 | --Testcase 26: 80 | DELETE FROM v4; 81 | 82 | --Testcase 27: 83 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 84 | 85 | -- Should not get that error once a user mapping is created and have enough information. 86 | --Testcase 28: 87 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 88 | -- For Foreign Scan, Foreign Modify. 89 | --Testcase 29: 90 | SELECT * FROM v4; 91 | --Testcase 30: 92 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 93 | --Testcase 31: 94 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 95 | --Testcase 32: 96 | DELETE FROM v4; 97 | 98 | -- Clean 99 | --Testcase 33: 100 | DROP VIEW v4; 101 | --Testcase 34: 102 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 103 | --Testcase 35: 104 | DROP OWNED BY regress_view_owner_another; 105 | --Testcase 36: 106 | DROP OWNED BY empty_owner; 107 | --Testcase 37: 108 | DROP ROLE regress_view_owner_another; 109 | --Testcase 38: 110 | -- current user cannot be dropped 111 | --Testcase 39: 112 | RESET ROLE; 113 | --Testcase 40: 114 | DROP ROLE empty_owner; 115 | --Testcase 41: 116 | DROP EXTENSION dynamodb_fdw CASCADE; 117 | -------------------------------------------------------------------------------- /dynamodb_fdw--1.0.sql: -------------------------------------------------------------------------------- 1 | /* contrib/dynamodb_fdw/dynamodb_fdw--1.0.sql */ 2 | 3 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 4 | \echo Use "CREATE EXTENSION dynamodb_fdw" to load this file. \quit 5 | 6 | CREATE FUNCTION dynamodb_fdw_handler() 7 | RETURNS fdw_handler 8 | AS 'MODULE_PATHNAME' 9 | LANGUAGE C STRICT; 10 | 11 | CREATE FUNCTION dynamodb_fdw_validator(text[], oid) 12 | RETURNS void 13 | AS 'MODULE_PATHNAME' 14 | LANGUAGE C STRICT; 15 | 16 | CREATE FOREIGN DATA WRAPPER dynamodb_fdw 17 | HANDLER dynamodb_fdw_handler 18 | VALIDATOR dynamodb_fdw_validator; 19 | 20 | CREATE PROCEDURE dynamodb_create_or_replace_stub(func_type text, name_arg text, return_type regtype) AS $$ 21 | DECLARE 22 | proname_raw text := split_part(name_arg, '(', 1); 23 | proname text := ltrim(rtrim(proname_raw)); 24 | BEGIN 25 | IF lower(func_type) = 'aggregation' OR lower(func_type) = 'aggregate' OR lower(func_type) = 'agg' OR lower(func_type) = 'a' THEN 26 | DECLARE 27 | proargs_raw text := right(name_arg, length(name_arg) - length(proname_raw)); 28 | proargs text := ltrim(rtrim(proargs_raw)); 29 | proargs_types text := right(left(proargs, length(proargs) - 1), length(proargs) - 2); 30 | aggproargs text := format('(%s, %s)', return_type, proargs_types); 31 | BEGIN 32 | BEGIN 33 | EXECUTE format(' 34 | CREATE FUNCTION %s_sfunc%s RETURNS %s IMMUTABLE AS $inner$ 35 | BEGIN 36 | RAISE EXCEPTION ''stub %s_sfunc%s is called''; 37 | RETURN NULL; 38 | END $inner$ LANGUAGE plpgsql;', 39 | proname, aggproargs, return_type, proname, aggproargs); 40 | EXCEPTION 41 | WHEN duplicate_function THEN 42 | RAISE DEBUG 'stub function for aggregation already exists (ignored)'; 43 | END; 44 | BEGIN 45 | EXECUTE format(' 46 | CREATE AGGREGATE %s 47 | ( 48 | sfunc = %s_sfunc, 49 | stype = %s 50 | );', name_arg, proname, return_type); 51 | EXCEPTION 52 | WHEN duplicate_function THEN 53 | RAISE DEBUG 'stub aggregation already exists (ignored)'; 54 | WHEN others THEN 55 | RAISE EXCEPTION 'stub aggregation exception'; 56 | END; 57 | END; 58 | ELSIF lower(func_type) = 'function' OR lower(func_type) = 'func' OR lower(func_type) = 'f' THEN 59 | BEGIN 60 | EXECUTE format(' 61 | CREATE FUNCTION %s RETURNS %s IMMUTABLE AS $inner$ 62 | BEGIN 63 | RAISE EXCEPTION ''stub %s is called''; 64 | RETURN NULL; 65 | END $inner$ LANGUAGE plpgsql COST 1;', 66 | name_arg, return_type, name_arg); 67 | EXCEPTION 68 | WHEN duplicate_function THEN 69 | RAISE DEBUG 'stub already exists (ignored)'; 70 | END; 71 | ELSEIF lower(func_type) = 'stable function' OR lower(func_type) = 'sfunc' OR lower(func_type) = 'sf' THEN 72 | BEGIN 73 | EXECUTE format(' 74 | CREATE FUNCTION %s RETURNS %s STABLE AS $inner$ 75 | BEGIN 76 | RAISE EXCEPTION ''stub %s is called''; 77 | RETURN NULL; 78 | END $inner$ LANGUAGE plpgsql COST 1;', 79 | name_arg, return_type, name_arg); 80 | EXCEPTION 81 | WHEN duplicate_function THEN 82 | RAISE DEBUG 'stub already exists (ignored)'; 83 | END; 84 | ELSEIF lower(func_type) = 'volatile function' OR lower(func_type) = 'vfunc' OR lower(func_type) = 'vf' THEN 85 | BEGIN 86 | EXECUTE format(' 87 | CREATE FUNCTION %s RETURNS %s VOLATILE AS $inner$ 88 | BEGIN 89 | RAISE EXCEPTION ''stub %s is called''; 90 | RETURN NULL; 91 | END $inner$ LANGUAGE plpgsql COST 1;', 92 | name_arg, return_type, name_arg); 93 | EXCEPTION 94 | WHEN duplicate_function THEN 95 | RAISE DEBUG 'stub already exists (ignored)'; 96 | END; 97 | ELSE 98 | RAISE EXCEPTION 'not supported function type %', func_type; 99 | BEGIN 100 | EXECUTE format(' 101 | CREATE FUNCTION %s_sfunc RETURNS %s AS $inner$ 102 | BEGIN 103 | RAISE EXCEPTION ''stub %s is called''; 104 | RETURN NULL; 105 | END $inner$ LANGUAGE plpgsql COST 1;', 106 | name_arg, return_type, name_arg); 107 | EXCEPTION 108 | WHEN duplicate_function THEN 109 | RAISE DEBUG 'stub already exists (ignored)'; 110 | END; 111 | END IF; 112 | END 113 | $$ LANGUAGE plpgsql; 114 | 115 | CALL dynamodb_create_or_replace_stub('f', 'size(anyelement)', 'bigint'); -------------------------------------------------------------------------------- /jansson/utf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include 9 | #include "utf.h" 10 | 11 | int utf8_encode(int32_t codepoint, char *buffer, size_t *size) 12 | { 13 | if(codepoint < 0) 14 | return -1; 15 | else if(codepoint < 0x80) 16 | { 17 | buffer[0] = (char)codepoint; 18 | *size = 1; 19 | } 20 | else if(codepoint < 0x800) 21 | { 22 | buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6); 23 | buffer[1] = 0x80 + ((codepoint & 0x03F)); 24 | *size = 2; 25 | } 26 | else if(codepoint < 0x10000) 27 | { 28 | buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12); 29 | buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6); 30 | buffer[2] = 0x80 + ((codepoint & 0x003F)); 31 | *size = 3; 32 | } 33 | else if(codepoint <= 0x10FFFF) 34 | { 35 | buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18); 36 | buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12); 37 | buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6); 38 | buffer[3] = 0x80 + ((codepoint & 0x00003F)); 39 | *size = 4; 40 | } 41 | else 42 | return -1; 43 | 44 | return 0; 45 | } 46 | 47 | size_t utf8_check_first(char byte) 48 | { 49 | unsigned char u = (unsigned char)byte; 50 | 51 | if(u < 0x80) 52 | return 1; 53 | 54 | if(0x80 <= u && u <= 0xBF) { 55 | /* second, third or fourth byte of a multi-byte 56 | sequence, i.e. a "continuation byte" */ 57 | return 0; 58 | } 59 | else if(u == 0xC0 || u == 0xC1) { 60 | /* overlong encoding of an ASCII byte */ 61 | return 0; 62 | } 63 | else if(0xC2 <= u && u <= 0xDF) { 64 | /* 2-byte sequence */ 65 | return 2; 66 | } 67 | 68 | else if(0xE0 <= u && u <= 0xEF) { 69 | /* 3-byte sequence */ 70 | return 3; 71 | } 72 | else if(0xF0 <= u && u <= 0xF4) { 73 | /* 4-byte sequence */ 74 | return 4; 75 | } 76 | else { /* u >= 0xF5 */ 77 | /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid 78 | UTF-8 */ 79 | return 0; 80 | } 81 | } 82 | 83 | size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint) 84 | { 85 | size_t i; 86 | int32_t value = 0; 87 | unsigned char u = (unsigned char)buffer[0]; 88 | 89 | if(size == 2) 90 | { 91 | value = u & 0x1F; 92 | } 93 | else if(size == 3) 94 | { 95 | value = u & 0xF; 96 | } 97 | else if(size == 4) 98 | { 99 | value = u & 0x7; 100 | } 101 | else 102 | return 0; 103 | 104 | for(i = 1; i < size; i++) 105 | { 106 | u = (unsigned char)buffer[i]; 107 | 108 | if(u < 0x80 || u > 0xBF) { 109 | /* not a continuation byte */ 110 | return 0; 111 | } 112 | 113 | value = (value << 6) + (u & 0x3F); 114 | } 115 | 116 | if(value > 0x10FFFF) { 117 | /* not in Unicode range */ 118 | return 0; 119 | } 120 | 121 | else if(0xD800 <= value && value <= 0xDFFF) { 122 | /* invalid code point (UTF-16 surrogate halves) */ 123 | return 0; 124 | } 125 | 126 | else if((size == 2 && value < 0x80) || 127 | (size == 3 && value < 0x800) || 128 | (size == 4 && value < 0x10000)) { 129 | /* overlong encoding */ 130 | return 0; 131 | } 132 | 133 | if(codepoint) 134 | *codepoint = value; 135 | 136 | return 1; 137 | } 138 | 139 | const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint) 140 | { 141 | size_t count; 142 | int32_t value; 143 | 144 | if(!bufsize) 145 | return buffer; 146 | 147 | count = utf8_check_first(buffer[0]); 148 | if(count <= 0) 149 | return NULL; 150 | 151 | if(count == 1) 152 | value = (unsigned char)buffer[0]; 153 | else 154 | { 155 | if(count > bufsize || !utf8_check_full(buffer, count, &value)) 156 | return NULL; 157 | } 158 | 159 | if(codepoint) 160 | *codepoint = value; 161 | 162 | return buffer + count; 163 | } 164 | 165 | int utf8_check_string(const char *string, size_t length) 166 | { 167 | size_t i; 168 | 169 | for(i = 0; i < length; i++) 170 | { 171 | size_t count = utf8_check_first(string[i]); 172 | if(count == 0) 173 | return 0; 174 | else if(count > 1) 175 | { 176 | if(count > length - i) 177 | return 0; 178 | 179 | if(!utf8_check_full(&string[i], count, NULL)) 180 | return 0; 181 | 182 | i += count - 1; 183 | } 184 | } 185 | 186 | return 1; 187 | } 188 | -------------------------------------------------------------------------------- /dynamodb_fdw.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * dynamodb_fdw.h 4 | * Foreign-data wrapper for DynamoDB 5 | * 6 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 7 | * 8 | * IDENTIFICATION 9 | * contrib/dynamodb_fdw/dynamodb_fdw.h 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | #ifndef DYNAMODB_FDW_H 14 | #define DYNAMODB_FDW_H 15 | 16 | #include "foreign/foreign.h" 17 | #include "lib/stringinfo.h" 18 | #include "nodes/pathnodes.h" 19 | #include "utils/relcache.h" 20 | #include "catalog/pg_operator.h" 21 | #define CODE_VERSION 10400 22 | 23 | /* 24 | * Options structure to store the dynamodb 25 | * server information 26 | */ 27 | typedef struct dynamodb_opt 28 | { 29 | char *svr_endpoint; /* dynamodb server ip address */ 30 | char *svr_username; /* dynamodb user name */ 31 | char *svr_password; /* dynamodb password */ 32 | char *svr_partition_key; /* dynamodb partition_key */ 33 | char *svr_sort_key; /* dynamodb sort_key */ 34 | } dynamodb_opt; 35 | 36 | /* 37 | * FDW-specific planner information kept in RelOptInfo.fdw_private for a 38 | * postgres_fdw foreign table. For a baserel, this struct is created by 39 | * postgresGetForeignRelSize, although some fields are not filled till later. 40 | * postgresGetForeignJoinPaths creates it for a joinrel, and 41 | * postgresGetForeignUpperPaths creates it for an upperrel. 42 | */ 43 | typedef struct DynamoDBFdwRelationInfo 44 | { 45 | /* 46 | * True means that the relation can be pushed down. Always true for simple 47 | * foreign scan. 48 | */ 49 | bool pushdown_safe; 50 | 51 | /* 52 | * Restriction clauses, divided into safe and unsafe to pushdown subsets. 53 | * All entries in these lists should have RestrictInfo wrappers; that 54 | * improves efficiency of selectivity and cost estimation. 55 | */ 56 | List *remote_conds; 57 | List *local_conds; 58 | 59 | /* Bitmap of attr numbers we need to fetch from the remote server. */ 60 | Bitmapset *attrs_used; 61 | 62 | /* Cost and selectivity of local_conds. */ 63 | QualCost local_conds_cost; 64 | Selectivity local_conds_sel; 65 | 66 | /* Estimated size and cost for a scan, join, or grouping/aggregation. */ 67 | double rows; 68 | int width; 69 | Cost startup_cost; 70 | Cost total_cost; 71 | 72 | /* 73 | * Estimated number of rows fetched from the foreign server, and costs 74 | * excluding costs for transferring those rows from the foreign server. 75 | * These are only used by estimate_path_cost_size(). 76 | */ 77 | double retrieved_rows; 78 | Cost rel_startup_cost; 79 | Cost rel_total_cost; 80 | 81 | /* Options extracted from catalogs. */ 82 | Cost fdw_startup_cost; 83 | Cost fdw_tuple_cost; 84 | List *shippable_extensions; /* OIDs of whitelisted extensions */ 85 | 86 | /* Cached catalog information. */ 87 | ForeignTable *table; 88 | ForeignServer *server; 89 | 90 | } DynamoDBFdwRelationInfo; 91 | 92 | typedef enum DynamoDBOperatorsSupport 93 | { 94 | OP_CONDITIONAL = 1, 95 | OP_JSON, 96 | OP_UNSUPPORT, 97 | } DynamoDBOperatorsSupport; 98 | 99 | /* in dynamodb_impl.cpp */ 100 | extern int dynamodb_set_transmission_modes(void); 101 | extern void dynamodb_reset_transmission_modes(int nestlevel); 102 | 103 | /* in option.c */ 104 | extern dynamodb_opt *dynamodb_get_options(Oid foreigntableid, Oid userid); 105 | 106 | /* in deparse.cpp */ 107 | extern void dynamodb_classify_conditions(PlannerInfo *root, 108 | RelOptInfo *baserel, 109 | List *input_conds, 110 | List **remote_conds, 111 | List **local_conds); 112 | extern bool dynamodb_is_foreign_expr(PlannerInfo *root, 113 | RelOptInfo *baserel, 114 | Expr *expr); 115 | extern void dynamodb_deparse_insert(StringInfo buf, RangeTblEntry *rte, 116 | Index rtindex, Relation rel, 117 | List *targetAttrs, List **retrieved_attrs); 118 | extern void dynamodb_deparse_delete(StringInfo buf, RangeTblEntry *rte, 119 | Index rtindex, Relation rel, 120 | List *returningList, 121 | List **retrieved_attrs, List *attnums); 122 | extern void dynamodb_deparse_update(StringInfo buf, RangeTblEntry *rte, 123 | Index rtindex, Relation rel, 124 | List *targetAttrs, 125 | List *withCheckOptionList, List *returningList, 126 | List **retrieved_attrs, List *attnums); 127 | extern void dynamodb_deparse_select_stmt_for_rel(StringInfo buf, PlannerInfo *root, 128 | RelOptInfo *foreignrel, List *tlist, 129 | List *remote_conds, List *pathkeys, 130 | List **retrieved_attrs); 131 | extern bool dynamodb_tlist_has_json_arrow_op(PlannerInfo *root, RelOptInfo *baserel, List *tlist); 132 | extern Form_pg_operator dynamodb_get_operator_expression(Oid oid); 133 | extern DynamoDBOperatorsSupport dynamodb_validate_operator_name(Form_pg_operator opform); 134 | extern void dynamodb_get_document_path(StringInfo buf, PlannerInfo *root, RelOptInfo *rel, Expr *expr); 135 | /* in shippable.c */ 136 | extern bool dynamodb_is_builtin(Oid objectId); 137 | extern bool dynamodb_is_shippable(Oid objectId, Oid classId, DynamoDBFdwRelationInfo *fpinfo); 138 | 139 | #endif /* DYNAMODB_FDW_H */ 140 | -------------------------------------------------------------------------------- /jansson/hashtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Petri Lehtinen 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef HASHTABLE_H 9 | #define HASHTABLE_H 10 | 11 | #include 12 | #include "jansson.h" 13 | 14 | struct hashtable_list { 15 | struct hashtable_list *prev; 16 | struct hashtable_list *next; 17 | }; 18 | 19 | /* "pair" may be a bit confusing a name, but think of it as a 20 | key-value pair. In this case, it just encodes some extra data, 21 | too */ 22 | struct hashtable_pair { 23 | struct hashtable_list list; 24 | struct hashtable_list ordered_list; 25 | size_t hash; 26 | json_t *value; 27 | char key[1]; 28 | }; 29 | 30 | struct hashtable_bucket { 31 | struct hashtable_list *first; 32 | struct hashtable_list *last; 33 | }; 34 | 35 | typedef struct hashtable { 36 | size_t size; 37 | struct hashtable_bucket *buckets; 38 | size_t order; /* hashtable has pow(2, order) buckets */ 39 | struct hashtable_list list; 40 | struct hashtable_list ordered_list; 41 | } hashtable_t; 42 | 43 | 44 | #define hashtable_key_to_iter(key_) \ 45 | (&(container_of(key_, struct hashtable_pair, key)->ordered_list)) 46 | 47 | 48 | /** 49 | * hashtable_init - Initialize a hashtable object 50 | * 51 | * @hashtable: The (statically allocated) hashtable object 52 | * 53 | * Initializes a statically allocated hashtable object. The object 54 | * should be cleared with hashtable_close when it's no longer used. 55 | * 56 | * Returns 0 on success, -1 on error (out of memory). 57 | */ 58 | int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS(warn_unused_result); 59 | 60 | /** 61 | * hashtable_close - Release all resources used by a hashtable object 62 | * 63 | * @hashtable: The hashtable 64 | * 65 | * Destroys a statically allocated hashtable object. 66 | */ 67 | void hashtable_close(hashtable_t *hashtable); 68 | 69 | /** 70 | * hashtable_set - Add/modify value in hashtable 71 | * 72 | * @hashtable: The hashtable object 73 | * @key: The key 74 | * @serial: For addition order of keys 75 | * @value: The value 76 | * 77 | * If a value with the given key already exists, its value is replaced 78 | * with the new value. Value is "stealed" in the sense that hashtable 79 | * doesn't increment its refcount but decreases the refcount when the 80 | * value is no longer needed. 81 | * 82 | * Returns 0 on success, -1 on failure (out of memory). 83 | */ 84 | int hashtable_set(hashtable_t *hashtable, const char *key, json_t *value); 85 | 86 | /** 87 | * hashtable_get - Get a value associated with a key 88 | * 89 | * @hashtable: The hashtable object 90 | * @key: The key 91 | * 92 | * Returns value if it is found, or NULL otherwise. 93 | */ 94 | void *hashtable_get(hashtable_t *hashtable, const char *key); 95 | 96 | /** 97 | * hashtable_del - Remove a value from the hashtable 98 | * 99 | * @hashtable: The hashtable object 100 | * @key: The key 101 | * 102 | * Returns 0 on success, or -1 if the key was not found. 103 | */ 104 | int hashtable_del(hashtable_t *hashtable, const char *key); 105 | 106 | /** 107 | * hashtable_clear - Clear hashtable 108 | * 109 | * @hashtable: The hashtable object 110 | * 111 | * Removes all items from the hashtable. 112 | */ 113 | void hashtable_clear(hashtable_t *hashtable); 114 | 115 | /** 116 | * hashtable_iter - Iterate over hashtable 117 | * 118 | * @hashtable: The hashtable object 119 | * 120 | * Returns an opaque iterator to the first element in the hashtable. 121 | * The iterator should be passed to hashtable_iter_* functions. 122 | * The hashtable items are not iterated over in any particular order. 123 | * 124 | * There's no need to free the iterator in any way. The iterator is 125 | * valid as long as the item that is referenced by the iterator is not 126 | * deleted. Other values may be added or deleted. In particular, 127 | * hashtable_iter_next() may be called on an iterator, and after that 128 | * the key/value pair pointed by the old iterator may be deleted. 129 | */ 130 | void *hashtable_iter(hashtable_t *hashtable); 131 | 132 | /** 133 | * hashtable_iter_at - Return an iterator at a specific key 134 | * 135 | * @hashtable: The hashtable object 136 | * @key: The key that the iterator should point to 137 | * 138 | * Like hashtable_iter() but returns an iterator pointing to a 139 | * specific key. 140 | */ 141 | void *hashtable_iter_at(hashtable_t *hashtable, const char *key); 142 | 143 | /** 144 | * hashtable_iter_next - Advance an iterator 145 | * 146 | * @hashtable: The hashtable object 147 | * @iter: The iterator 148 | * 149 | * Returns a new iterator pointing to the next element in the 150 | * hashtable or NULL if the whole hastable has been iterated over. 151 | */ 152 | void *hashtable_iter_next(hashtable_t *hashtable, void *iter); 153 | 154 | /** 155 | * hashtable_iter_key - Retrieve the key pointed by an iterator 156 | * 157 | * @iter: The iterator 158 | */ 159 | void *hashtable_iter_key(void *iter); 160 | 161 | /** 162 | * hashtable_iter_value - Retrieve the value pointed by an iterator 163 | * 164 | * @iter: The iterator 165 | */ 166 | void *hashtable_iter_value(void *iter); 167 | 168 | /** 169 | * hashtable_iter_set - Set the value pointed by an iterator 170 | * 171 | * @iter: The iterator 172 | * @value: The value to set 173 | */ 174 | void hashtable_iter_set(void *iter, json_t *value); 175 | 176 | #endif 177 | -------------------------------------------------------------------------------- /expected/15.7/dynamodb_fdw.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | -- Get version 8 | --Testcase 42: 9 | SELECT * FROM public.dynamodb_fdw_version(); 10 | dynamodb_fdw_version 11 | ---------------------- 12 | 10400 13 | (1 row) 14 | 15 | --Testcase 43: 16 | SELECT dynamodb_fdw_version(); 17 | dynamodb_fdw_version 18 | ---------------------- 19 | 10400 20 | (1 row) 21 | 22 | -- ==================================================================== 23 | -- Check that userid to use when querying the remote table is correctly 24 | -- propagated into foreign rels. 25 | -- ==================================================================== 26 | -- create empty_owner without access information to detect incorrect UserID. 27 | --Testcase 3: 28 | CREATE ROLE empty_owner LOGIN SUPERUSER; 29 | --Testcase 4: 30 | SET ROLE empty_owner; 31 | --Testcase 5: 32 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 33 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 34 | --Testcase 6: 35 | CREATE VIEW v4 AS SELECT * FROM example1; 36 | -- If undefine user owner, postgres core defaults to using the current user to query. 37 | -- For Foreign Scan, Foreign Modify. 38 | --Testcase 7: 39 | SELECT * FROM v4; 40 | ERROR: user mapping not found for "empty_owner" 41 | --Testcase 8: 42 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 43 | ERROR: user mapping not found for "empty_owner" 44 | --Testcase 9: 45 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 46 | ERROR: user mapping not found for "empty_owner" 47 | --Testcase 10: 48 | DELETE FROM v4; 49 | ERROR: user mapping not found for "empty_owner" 50 | --Testcase 11: 51 | CREATE ROLE regress_view_owner_another; 52 | --Testcase 12: 53 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 54 | --Testcase 13: 55 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 56 | --Testcase 14: 57 | GRANT SELECT ON example1 TO regress_view_owner_another; 58 | --Testcase 15: 59 | GRANT INSERT ON example1 TO regress_view_owner_another; 60 | --Testcase 16: 61 | GRANT UPDATE ON example1 TO regress_view_owner_another; 62 | --Testcase 17: 63 | GRANT DELETE ON example1 TO regress_view_owner_another; 64 | -- It fails as expected due to the lack of a user mapping for that user. 65 | -- For Foreign Scan, Foreign Modify. 66 | --Testcase 18: 67 | SELECT * FROM v4; 68 | ERROR: user mapping not found for "regress_view_owner_another" 69 | --Testcase 19: 70 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 71 | ERROR: user mapping not found for "regress_view_owner_another" 72 | --Testcase 20: 73 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 74 | ERROR: user mapping not found for "regress_view_owner_another" 75 | --Testcase 21: 76 | DELETE FROM v4; 77 | ERROR: user mapping not found for "regress_view_owner_another" 78 | -- Identify the correct user, but it fails due to the lack access informations. 79 | --Testcase 22: 80 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 81 | -- For Foreign Scan, Foreign Modify. 82 | --Testcase 23: 83 | SELECT * FROM v4; 84 | ERROR: dynamodb_fdw: password is required 85 | DETAIL: Non-superusers must provide a password in the user mapping. 86 | --Testcase 24: 87 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 88 | ERROR: dynamodb_fdw: password is required 89 | DETAIL: Non-superusers must provide a password in the user mapping. 90 | --Testcase 25: 91 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 92 | ERROR: dynamodb_fdw: password is required 93 | DETAIL: Non-superusers must provide a password in the user mapping. 94 | --Testcase 26: 95 | DELETE FROM v4; 96 | ERROR: dynamodb_fdw: password is required 97 | DETAIL: Non-superusers must provide a password in the user mapping. 98 | --Testcase 27: 99 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 100 | -- Should not get that error once a user mapping is created and have enough information. 101 | --Testcase 28: 102 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 103 | -- For Foreign Scan, Foreign Modify. 104 | --Testcase 29: 105 | SELECT * FROM v4; 106 | artist | songtitle | albumtitle 107 | -----------------+---------------------+------------------ 108 | 9 | SomE oNe LiKE yOu | RECORD INSERTED 109 | Acme Band | Happy Day | Songs About Life 110 | 8 | SomE oNe LiKE yOu | RECORD INSERTED 111 | No One You Know | Call Me Today | Somewhat Famous 112 | No One You Know | Scared of My Shadow | Blue Sky Blues 113 | (5 rows) 114 | 115 | --Testcase 30: 116 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 117 | --Testcase 31: 118 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 119 | --Testcase 32: 120 | DELETE FROM v4; 121 | -- Clean 122 | --Testcase 33: 123 | DROP VIEW v4; 124 | --Testcase 34: 125 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 126 | --Testcase 35: 127 | DROP OWNED BY regress_view_owner_another; 128 | --Testcase 36: 129 | DROP OWNED BY empty_owner; 130 | --Testcase 37: 131 | DROP ROLE regress_view_owner_another; 132 | --Testcase 38: 133 | -- current user cannot be dropped 134 | --Testcase 39: 135 | RESET ROLE; 136 | --Testcase 40: 137 | DROP ROLE empty_owner; 138 | --Testcase 41: 139 | DROP EXTENSION dynamodb_fdw CASCADE; 140 | NOTICE: drop cascades to server dynamodb_server 141 | -------------------------------------------------------------------------------- /expected/16.3/dynamodb_fdw.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | -- Get version 8 | --Testcase 42: 9 | SELECT * FROM public.dynamodb_fdw_version(); 10 | dynamodb_fdw_version 11 | ---------------------- 12 | 10400 13 | (1 row) 14 | 15 | --Testcase 43: 16 | SELECT dynamodb_fdw_version(); 17 | dynamodb_fdw_version 18 | ---------------------- 19 | 10400 20 | (1 row) 21 | 22 | -- ==================================================================== 23 | -- Check that userid to use when querying the remote table is correctly 24 | -- propagated into foreign rels. 25 | -- ==================================================================== 26 | -- create empty_owner without access information to detect incorrect UserID. 27 | --Testcase 3: 28 | CREATE ROLE empty_owner LOGIN SUPERUSER; 29 | --Testcase 4: 30 | SET ROLE empty_owner; 31 | --Testcase 5: 32 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 33 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 34 | --Testcase 6: 35 | CREATE VIEW v4 AS SELECT * FROM example1; 36 | -- If undefine user owner, postgres core defaults to using the current user to query. 37 | -- For Foreign Scan, Foreign Modify. 38 | --Testcase 7: 39 | SELECT * FROM v4; 40 | ERROR: user mapping not found for "empty_owner" 41 | --Testcase 8: 42 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 43 | ERROR: user mapping not found for "empty_owner" 44 | --Testcase 9: 45 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 46 | ERROR: user mapping not found for "empty_owner" 47 | --Testcase 10: 48 | DELETE FROM v4; 49 | ERROR: user mapping not found for "empty_owner" 50 | --Testcase 11: 51 | CREATE ROLE regress_view_owner_another; 52 | --Testcase 12: 53 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 54 | --Testcase 13: 55 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 56 | --Testcase 14: 57 | GRANT SELECT ON example1 TO regress_view_owner_another; 58 | --Testcase 15: 59 | GRANT INSERT ON example1 TO regress_view_owner_another; 60 | --Testcase 16: 61 | GRANT UPDATE ON example1 TO regress_view_owner_another; 62 | --Testcase 17: 63 | GRANT DELETE ON example1 TO regress_view_owner_another; 64 | -- It fails as expected due to the lack of a user mapping for that user. 65 | -- For Foreign Scan, Foreign Modify. 66 | --Testcase 18: 67 | SELECT * FROM v4; 68 | ERROR: user mapping not found for "regress_view_owner_another" 69 | --Testcase 19: 70 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 71 | ERROR: user mapping not found for "regress_view_owner_another" 72 | --Testcase 20: 73 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 74 | ERROR: user mapping not found for "regress_view_owner_another" 75 | --Testcase 21: 76 | DELETE FROM v4; 77 | ERROR: user mapping not found for "regress_view_owner_another" 78 | -- Identify the correct user, but it fails due to the lack access informations. 79 | --Testcase 22: 80 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 81 | -- For Foreign Scan, Foreign Modify. 82 | --Testcase 23: 83 | SELECT * FROM v4; 84 | ERROR: dynamodb_fdw: password is required 85 | DETAIL: Non-superusers must provide a password in the user mapping. 86 | --Testcase 24: 87 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 88 | ERROR: dynamodb_fdw: password is required 89 | DETAIL: Non-superusers must provide a password in the user mapping. 90 | --Testcase 25: 91 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 92 | ERROR: dynamodb_fdw: password is required 93 | DETAIL: Non-superusers must provide a password in the user mapping. 94 | --Testcase 26: 95 | DELETE FROM v4; 96 | ERROR: dynamodb_fdw: password is required 97 | DETAIL: Non-superusers must provide a password in the user mapping. 98 | --Testcase 27: 99 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 100 | -- Should not get that error once a user mapping is created and have enough information. 101 | --Testcase 28: 102 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 103 | -- For Foreign Scan, Foreign Modify. 104 | --Testcase 29: 105 | SELECT * FROM v4; 106 | artist | songtitle | albumtitle 107 | -----------------+---------------------+------------------ 108 | 9 | SomE oNe LiKE yOu | RECORD INSERTED 109 | Acme Band | Happy Day | Songs About Life 110 | 8 | SomE oNe LiKE yOu | RECORD INSERTED 111 | No One You Know | Call Me Today | Somewhat Famous 112 | No One You Know | Scared of My Shadow | Blue Sky Blues 113 | (5 rows) 114 | 115 | --Testcase 30: 116 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 117 | --Testcase 31: 118 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 119 | --Testcase 32: 120 | DELETE FROM v4; 121 | -- Clean 122 | --Testcase 33: 123 | DROP VIEW v4; 124 | --Testcase 34: 125 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 126 | --Testcase 35: 127 | DROP OWNED BY regress_view_owner_another; 128 | --Testcase 36: 129 | DROP OWNED BY empty_owner; 130 | --Testcase 37: 131 | DROP ROLE regress_view_owner_another; 132 | --Testcase 38: 133 | -- current user cannot be dropped 134 | --Testcase 39: 135 | RESET ROLE; 136 | --Testcase 40: 137 | DROP ROLE empty_owner; 138 | --Testcase 41: 139 | DROP EXTENSION dynamodb_fdw CASCADE; 140 | NOTICE: drop cascades to server dynamodb_server 141 | -------------------------------------------------------------------------------- /expected/13.15/dynamodb_fdw.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | -- Get version 8 | --Testcase 42: 9 | SELECT * FROM public.dynamodb_fdw_version(); 10 | dynamodb_fdw_version 11 | ---------------------- 12 | 10400 13 | (1 row) 14 | 15 | --Testcase 43: 16 | SELECT dynamodb_fdw_version(); 17 | dynamodb_fdw_version 18 | ---------------------- 19 | 10400 20 | (1 row) 21 | 22 | -- ==================================================================== 23 | -- Check that userid to use when querying the remote table is correctly 24 | -- propagated into foreign rels. 25 | -- ==================================================================== 26 | -- create empty_owner without access information to detect incorrect UserID. 27 | --Testcase 3: 28 | CREATE ROLE empty_owner LOGIN SUPERUSER; 29 | --Testcase 4: 30 | SET ROLE empty_owner; 31 | --Testcase 5: 32 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 33 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 34 | --Testcase 6: 35 | CREATE VIEW v4 AS SELECT * FROM example1; 36 | -- If undefine user owner, postgres core defaults to using the current user to query. 37 | -- For Foreign Scan, Foreign Modify. 38 | --Testcase 7: 39 | SELECT * FROM v4; 40 | ERROR: user mapping not found for "empty_owner" 41 | --Testcase 8: 42 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 43 | ERROR: user mapping not found for "empty_owner" 44 | --Testcase 9: 45 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 46 | ERROR: user mapping not found for "empty_owner" 47 | --Testcase 10: 48 | DELETE FROM v4; 49 | ERROR: user mapping not found for "empty_owner" 50 | --Testcase 11: 51 | CREATE ROLE regress_view_owner_another; 52 | --Testcase 12: 53 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 54 | --Testcase 13: 55 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 56 | --Testcase 14: 57 | GRANT SELECT ON example1 TO regress_view_owner_another; 58 | --Testcase 15: 59 | GRANT INSERT ON example1 TO regress_view_owner_another; 60 | --Testcase 16: 61 | GRANT UPDATE ON example1 TO regress_view_owner_another; 62 | --Testcase 17: 63 | GRANT DELETE ON example1 TO regress_view_owner_another; 64 | -- It fails as expected due to the lack of a user mapping for that user. 65 | -- For Foreign Scan, Foreign Modify. 66 | --Testcase 18: 67 | SELECT * FROM v4; 68 | ERROR: user mapping not found for "regress_view_owner_another" 69 | --Testcase 19: 70 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 71 | ERROR: user mapping not found for "regress_view_owner_another" 72 | --Testcase 20: 73 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 74 | ERROR: user mapping not found for "regress_view_owner_another" 75 | --Testcase 21: 76 | DELETE FROM v4; 77 | ERROR: user mapping not found for "regress_view_owner_another" 78 | -- Identify the correct user, but it fails due to the lack access informations. 79 | --Testcase 22: 80 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 81 | -- For Foreign Scan, Foreign Modify. 82 | --Testcase 23: 83 | SELECT * FROM v4; 84 | ERROR: dynamodb_fdw: password is required 85 | DETAIL: Non-superusers must provide a password in the user mapping. 86 | --Testcase 24: 87 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 88 | ERROR: dynamodb_fdw: password is required 89 | DETAIL: Non-superusers must provide a password in the user mapping. 90 | --Testcase 25: 91 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 92 | ERROR: dynamodb_fdw: password is required 93 | DETAIL: Non-superusers must provide a password in the user mapping. 94 | --Testcase 26: 95 | DELETE FROM v4; 96 | ERROR: dynamodb_fdw: password is required 97 | DETAIL: Non-superusers must provide a password in the user mapping. 98 | --Testcase 27: 99 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 100 | -- Should not get that error once a user mapping is created and have enough information. 101 | --Testcase 28: 102 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 103 | -- For Foreign Scan, Foreign Modify. 104 | --Testcase 29: 105 | SELECT * FROM v4; 106 | artist | songtitle | albumtitle 107 | -----------------+---------------------+------------------ 108 | 9 | SomE oNe LiKE yOu | RECORD INSERTED 109 | Acme Band | Happy Day | Songs About Life 110 | 8 | SomE oNe LiKE yOu | RECORD INSERTED 111 | No One You Know | Call Me Today | Somewhat Famous 112 | No One You Know | Scared of My Shadow | Blue Sky Blues 113 | (5 rows) 114 | 115 | --Testcase 30: 116 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 117 | --Testcase 31: 118 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 119 | --Testcase 32: 120 | DELETE FROM v4; 121 | -- Clean 122 | --Testcase 33: 123 | DROP VIEW v4; 124 | --Testcase 34: 125 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 126 | --Testcase 35: 127 | DROP OWNED BY regress_view_owner_another; 128 | --Testcase 36: 129 | DROP OWNED BY empty_owner; 130 | --Testcase 37: 131 | DROP ROLE regress_view_owner_another; 132 | --Testcase 38: 133 | -- current user cannot be dropped 134 | --Testcase 39: 135 | RESET ROLE; 136 | --Testcase 40: 137 | DROP ROLE empty_owner; 138 | --Testcase 41: 139 | DROP EXTENSION dynamodb_fdw CASCADE; 140 | NOTICE: drop cascades to server dynamodb_server 141 | -------------------------------------------------------------------------------- /expected/14.12/dynamodb_fdw.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | -- Get version 8 | --Testcase 42: 9 | SELECT * FROM public.dynamodb_fdw_version(); 10 | dynamodb_fdw_version 11 | ---------------------- 12 | 10400 13 | (1 row) 14 | 15 | --Testcase 43: 16 | SELECT dynamodb_fdw_version(); 17 | dynamodb_fdw_version 18 | ---------------------- 19 | 10400 20 | (1 row) 21 | 22 | -- ==================================================================== 23 | -- Check that userid to use when querying the remote table is correctly 24 | -- propagated into foreign rels. 25 | -- ==================================================================== 26 | -- create empty_owner without access information to detect incorrect UserID. 27 | --Testcase 3: 28 | CREATE ROLE empty_owner LOGIN SUPERUSER; 29 | --Testcase 4: 30 | SET ROLE empty_owner; 31 | --Testcase 5: 32 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 33 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 34 | --Testcase 6: 35 | CREATE VIEW v4 AS SELECT * FROM example1; 36 | -- If undefine user owner, postgres core defaults to using the current user to query. 37 | -- For Foreign Scan, Foreign Modify. 38 | --Testcase 7: 39 | SELECT * FROM v4; 40 | ERROR: user mapping not found for "empty_owner" 41 | --Testcase 8: 42 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 43 | ERROR: user mapping not found for "empty_owner" 44 | --Testcase 9: 45 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 46 | ERROR: user mapping not found for "empty_owner" 47 | --Testcase 10: 48 | DELETE FROM v4; 49 | ERROR: user mapping not found for "empty_owner" 50 | --Testcase 11: 51 | CREATE ROLE regress_view_owner_another; 52 | --Testcase 12: 53 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 54 | --Testcase 13: 55 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 56 | --Testcase 14: 57 | GRANT SELECT ON example1 TO regress_view_owner_another; 58 | --Testcase 15: 59 | GRANT INSERT ON example1 TO regress_view_owner_another; 60 | --Testcase 16: 61 | GRANT UPDATE ON example1 TO regress_view_owner_another; 62 | --Testcase 17: 63 | GRANT DELETE ON example1 TO regress_view_owner_another; 64 | -- It fails as expected due to the lack of a user mapping for that user. 65 | -- For Foreign Scan, Foreign Modify. 66 | --Testcase 18: 67 | SELECT * FROM v4; 68 | ERROR: user mapping not found for "regress_view_owner_another" 69 | --Testcase 19: 70 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 71 | ERROR: user mapping not found for "regress_view_owner_another" 72 | --Testcase 20: 73 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 74 | ERROR: user mapping not found for "regress_view_owner_another" 75 | --Testcase 21: 76 | DELETE FROM v4; 77 | ERROR: user mapping not found for "regress_view_owner_another" 78 | -- Identify the correct user, but it fails due to the lack access informations. 79 | --Testcase 22: 80 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 81 | -- For Foreign Scan, Foreign Modify. 82 | --Testcase 23: 83 | SELECT * FROM v4; 84 | ERROR: dynamodb_fdw: password is required 85 | DETAIL: Non-superusers must provide a password in the user mapping. 86 | --Testcase 24: 87 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 88 | ERROR: dynamodb_fdw: password is required 89 | DETAIL: Non-superusers must provide a password in the user mapping. 90 | --Testcase 25: 91 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 92 | ERROR: dynamodb_fdw: password is required 93 | DETAIL: Non-superusers must provide a password in the user mapping. 94 | --Testcase 26: 95 | DELETE FROM v4; 96 | ERROR: dynamodb_fdw: password is required 97 | DETAIL: Non-superusers must provide a password in the user mapping. 98 | --Testcase 27: 99 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 100 | -- Should not get that error once a user mapping is created and have enough information. 101 | --Testcase 28: 102 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 103 | -- For Foreign Scan, Foreign Modify. 104 | --Testcase 29: 105 | SELECT * FROM v4; 106 | artist | songtitle | albumtitle 107 | -----------------+---------------------+------------------ 108 | 9 | SomE oNe LiKE yOu | RECORD INSERTED 109 | Acme Band | Happy Day | Songs About Life 110 | 8 | SomE oNe LiKE yOu | RECORD INSERTED 111 | No One You Know | Call Me Today | Somewhat Famous 112 | No One You Know | Scared of My Shadow | Blue Sky Blues 113 | (5 rows) 114 | 115 | --Testcase 30: 116 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 117 | --Testcase 31: 118 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 119 | --Testcase 32: 120 | DELETE FROM v4; 121 | -- Clean 122 | --Testcase 33: 123 | DROP VIEW v4; 124 | --Testcase 34: 125 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 126 | --Testcase 35: 127 | DROP OWNED BY regress_view_owner_another; 128 | --Testcase 36: 129 | DROP OWNED BY empty_owner; 130 | --Testcase 37: 131 | DROP ROLE regress_view_owner_another; 132 | --Testcase 38: 133 | -- current user cannot be dropped 134 | --Testcase 39: 135 | RESET ROLE; 136 | --Testcase 40: 137 | DROP ROLE empty_owner; 138 | --Testcase 41: 139 | DROP EXTENSION dynamodb_fdw CASCADE; 140 | NOTICE: drop cascades to server dynamodb_server 141 | -------------------------------------------------------------------------------- /jansson/jansson_private_config.h: -------------------------------------------------------------------------------- 1 | /* jansson_private_config.h. Generated from jansson_private_config.h.in by configure. */ 2 | /* jansson_private_config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if gcc's __atomic builtins are available */ 5 | #define HAVE_ATOMIC_BUILTINS 1 6 | 7 | /* Define to 1 if you have the `close' function. */ 8 | #define HAVE_CLOSE 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_DLFCN_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_ENDIAN_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_FCNTL_H 1 18 | 19 | /* Define to 1 if you have the `getpid' function. */ 20 | #define HAVE_GETPID 1 21 | 22 | /* Define to 1 if you have the `gettimeofday' function. */ 23 | #define HAVE_GETTIMEOFDAY 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_INTTYPES_H 1 27 | 28 | /* Define to 1 if you have the `localeconv' function. */ 29 | #define HAVE_LOCALECONV 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_LOCALE_H 1 33 | 34 | /* Define to 1 if the system has the type 'long long int'. */ 35 | #define HAVE_LONG_LONG_INT 1 36 | 37 | /* Define to 1 if you have the header file. */ 38 | #define HAVE_MEMORY_H 1 39 | 40 | /* Define to 1 if you have the `open' function. */ 41 | #define HAVE_OPEN 1 42 | 43 | /* Define to 1 if you have the `read' function. */ 44 | #define HAVE_READ 1 45 | 46 | /* Define to 1 if you have the header file. */ 47 | #define HAVE_SCHED_H 1 48 | 49 | /* Define to 1 if you have the `sched_yield' function. */ 50 | #define HAVE_SCHED_YIELD 1 51 | 52 | /* Define to 1 if you have the header file. */ 53 | #define HAVE_STDINT_H 1 54 | 55 | /* Define to 1 if you have the header file. */ 56 | #define HAVE_STDLIB_H 1 57 | 58 | /* Define to 1 if you have the header file. */ 59 | #define HAVE_STRINGS_H 1 60 | 61 | /* Define to 1 if you have the header file. */ 62 | #define HAVE_STRING_H 1 63 | 64 | /* Define to 1 if you have the `strtoll' function. */ 65 | #define HAVE_STRTOLL 1 66 | 67 | /* Define to 1 if gcc's __sync builtins are available */ 68 | #define HAVE_SYNC_BUILTINS 1 69 | 70 | /* Define to 1 if you have the header file. */ 71 | #define HAVE_SYS_PARAM_H 1 72 | 73 | /* Define to 1 if you have the header file. */ 74 | #define HAVE_SYS_STAT_H 1 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #define HAVE_SYS_TIME_H 1 78 | 79 | /* Define to 1 if you have the header file. */ 80 | #define HAVE_SYS_TYPES_H 1 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #define HAVE_UNISTD_H 1 84 | 85 | /* Define to 1 if the system has the type 'unsigned long long int'. */ 86 | #define HAVE_UNSIGNED_LONG_LONG_INT 1 87 | 88 | /* Number of buckets new object hashtables contain is 2 raised to this power. 89 | E.g. 3 -> 2^3 = 8. */ 90 | #define INITIAL_HASHTABLE_ORDER 3 91 | 92 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 93 | */ 94 | #define LT_OBJDIR ".libs/" 95 | 96 | /* Name of package */ 97 | #define PACKAGE "jansson" 98 | 99 | /* Define to the address where bug reports for this package should be sent. */ 100 | #define PACKAGE_BUGREPORT "petri@digip.org" 101 | 102 | /* Define to the full name of this package. */ 103 | #define PACKAGE_NAME "jansson" 104 | 105 | /* Define to the full name and version of this package. */ 106 | #define PACKAGE_STRING "jansson 2.12" 107 | 108 | /* Define to the one symbol short name of this package. */ 109 | #define PACKAGE_TARNAME "jansson" 110 | 111 | /* Define to the home page for this package. */ 112 | #define PACKAGE_URL "" 113 | 114 | /* Define to the version of this package. */ 115 | #define PACKAGE_VERSION "2.12" 116 | 117 | /* Define to 1 if you have the ANSI C header files. */ 118 | #define STDC_HEADERS 1 119 | 120 | /* Define to 1 if /dev/urandom should be used for seeding the hash function */ 121 | #define USE_URANDOM 1 122 | 123 | /* Define to 1 if CryptGenRandom should be used for seeding the hash function 124 | */ 125 | #define USE_WINDOWS_CRYPTOAPI 1 126 | 127 | /* Version number of package */ 128 | #define VERSION "2.12" 129 | 130 | /* Define for Solaris 2.5.1 so the uint32_t typedef from , 131 | , or is not used. If the typedef were allowed, the 132 | #define below would cause a syntax error. */ 133 | /* #undef _UINT32_T */ 134 | 135 | /* Define for Solaris 2.5.1 so the uint8_t typedef from , 136 | , or is not used. If the typedef were allowed, the 137 | #define below would cause a syntax error. */ 138 | /* #undef _UINT8_T */ 139 | 140 | /* Define to `__inline__' or `__inline' if that's what the C compiler 141 | calls it, or to nothing if 'inline' is not supported under any name. */ 142 | #ifndef __cplusplus 143 | /* #undef inline */ 144 | #endif 145 | 146 | /* Define to the type of a signed integer type of width exactly 32 bits if 147 | such a type exists and the standard includes do not define it. */ 148 | /* #undef int32_t */ 149 | 150 | /* Define to the type of an unsigned integer type of width exactly 16 bits if 151 | such a type exists and the standard includes do not define it. */ 152 | /* #undef uint16_t */ 153 | 154 | /* Define to the type of an unsigned integer type of width exactly 32 bits if 155 | such a type exists and the standard includes do not define it. */ 156 | /* #undef uint32_t */ 157 | 158 | /* Define to the type of an unsigned integer type of width exactly 8 bits if 159 | such a type exists and the standard includes do not define it. */ 160 | /* #undef uint8_t */ 161 | -------------------------------------------------------------------------------- /sql/15.7/connection_validation.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Create foreign tables and validate 17 | --Testcase 4: 18 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 19 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 20 | 21 | --Testcase 5: 22 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 23 | 24 | 25 | -- Drop foreign table and create it again without partition_key and sort_key 26 | --Testcase 6: 27 | DROP FOREIGN TABLE connection_tbl; 28 | --Testcase 7: 29 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 30 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 33 | -- Should fail with an error 34 | --Testcase 9: 35 | INSERT INTO connection_tbl VALUES ('9', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 36 | --Testcase 10: 37 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '9'; 38 | --Testcase 11: 39 | DELETE FROM connection_tbl WHERE artist = '9'; 40 | --Testcase 12: 41 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 42 | 43 | 44 | -- Drop foreign table and create it again with invalid partition_key and valid sort_key 45 | --Testcase 13: 46 | DROP FOREIGN TABLE connection_tbl; 47 | --Testcase 14: 48 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 49 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'wrong', sort_key 'songtitle'); 50 | --Testcase 15: 51 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 52 | -- Should fail with an error 53 | --Testcase 16: 54 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 55 | --Testcase 17: 56 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 57 | --Testcase 18: 58 | DELETE FROM connection_tbl WHERE artist = '8'; 59 | --Testcase 19: 60 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 61 | 62 | -- Drop foreign table and create it again with valid partition_key and invalid sort_key 63 | --Testcase 20: 64 | DROP FOREIGN TABLE connection_tbl; 65 | --Testcase 21: 66 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 67 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'wrong'); 68 | -- Should fail with an error 69 | --Testcase 22: 70 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 71 | --Testcase 23: 72 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 73 | -- Should fail to update/delete the data with an error 74 | --Testcase 24: 75 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 76 | --Testcase 25: 77 | DELETE FROM connection_tbl WHERE artist = '8'; 78 | --Testcase 26: 79 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 80 | 81 | 82 | -- Alter one of the SERVER option 83 | -- Set correct partition_key and sort_key for dynamodb_server 84 | --Testcase 27: 85 | DROP FOREIGN TABLE connection_tbl; 86 | --Testcase 28: 87 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 88 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 89 | -- Set wrong endpoint for dynamodb_server 90 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint 'http://localhost:6868'); 91 | -- Should fail with an error 92 | --Testcase 29: 93 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 94 | --Testcase 30: 95 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '1'; 96 | --Testcase 31: 97 | DELETE FROM connection_tbl WHERE artist = '1'; 98 | --Testcase 32: 99 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 100 | -- Set correct address for dynamodb_server 101 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint :DYNAMODB_ENDPOINT); 102 | -- Should able to insert the data 103 | --Testcase 33: 104 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 105 | --Testcase 34: 106 | DELETE FROM connection_tbl WHERE artist = '1'; 107 | 108 | 109 | -- Drop user mapping and create with invalid user and password for public 110 | -- user mapping 111 | --Testcase 35: 112 | DROP USER MAPPING FOR public SERVER dynamodb_server; 113 | --Testcase 36: 114 | CREATE USER MAPPING FOR public SERVER dynamodb_server 115 | OPTIONS (user 'wrong', password 'wrong'); 116 | -- Should fail with an error 117 | --Testcase 37: 118 | INSERT INTO connection_tbl VALUES ('2', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 119 | --Testcase 38: 120 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '2'; 121 | --Testcase 39: 122 | DELETE FROM connection_tbl WHERE artist = '2'; 123 | -- Drop user mapping and create without username and password for public 124 | -- user mapping 125 | --Testcase 40: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 41: 128 | CREATE USER MAPPING FOR public SERVER dynamodb_server; 129 | -- Should fail with an error 130 | --Testcase 42: 131 | INSERT INTO connection_tbl VALUES ('3', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 132 | --Testcase 43: 133 | DELETE FROM connection_tbl WHERE artist = '3'; 134 | 135 | --Testcase 44: 136 | DROP USER MAPPING FOR public SERVER dynamodb_server; 137 | --Testcase 45: 138 | DROP EXTENSION dynamodb_fdw CASCADE; 139 | -------------------------------------------------------------------------------- /sql/16.3/connection_validation.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Create foreign tables and validate 17 | --Testcase 4: 18 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 19 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 20 | 21 | --Testcase 5: 22 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 23 | 24 | 25 | -- Drop foreign table and create it again without partition_key and sort_key 26 | --Testcase 6: 27 | DROP FOREIGN TABLE connection_tbl; 28 | --Testcase 7: 29 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 30 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 33 | -- Should fail with an error 34 | --Testcase 9: 35 | INSERT INTO connection_tbl VALUES ('9', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 36 | --Testcase 10: 37 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '9'; 38 | --Testcase 11: 39 | DELETE FROM connection_tbl WHERE artist = '9'; 40 | --Testcase 12: 41 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 42 | 43 | 44 | -- Drop foreign table and create it again with invalid partition_key and valid sort_key 45 | --Testcase 13: 46 | DROP FOREIGN TABLE connection_tbl; 47 | --Testcase 14: 48 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 49 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'wrong', sort_key 'songtitle'); 50 | --Testcase 15: 51 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 52 | -- Should fail with an error 53 | --Testcase 16: 54 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 55 | --Testcase 17: 56 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 57 | --Testcase 18: 58 | DELETE FROM connection_tbl WHERE artist = '8'; 59 | --Testcase 19: 60 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 61 | 62 | -- Drop foreign table and create it again with valid partition_key and invalid sort_key 63 | --Testcase 20: 64 | DROP FOREIGN TABLE connection_tbl; 65 | --Testcase 21: 66 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 67 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'wrong'); 68 | -- Should fail with an error 69 | --Testcase 22: 70 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 71 | --Testcase 23: 72 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 73 | -- Should fail to update/delete the data with an error 74 | --Testcase 24: 75 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 76 | --Testcase 25: 77 | DELETE FROM connection_tbl WHERE artist = '8'; 78 | --Testcase 26: 79 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 80 | 81 | 82 | -- Alter one of the SERVER option 83 | -- Set correct partition_key and sort_key for dynamodb_server 84 | --Testcase 27: 85 | DROP FOREIGN TABLE connection_tbl; 86 | --Testcase 28: 87 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 88 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 89 | -- Set wrong endpoint for dynamodb_server 90 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint 'http://localhost:6868'); 91 | -- Should fail with an error 92 | --Testcase 29: 93 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 94 | --Testcase 30: 95 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '1'; 96 | --Testcase 31: 97 | DELETE FROM connection_tbl WHERE artist = '1'; 98 | --Testcase 32: 99 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 100 | -- Set correct address for dynamodb_server 101 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint :DYNAMODB_ENDPOINT); 102 | -- Should able to insert the data 103 | --Testcase 33: 104 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 105 | --Testcase 34: 106 | DELETE FROM connection_tbl WHERE artist = '1'; 107 | 108 | 109 | -- Drop user mapping and create with invalid user and password for public 110 | -- user mapping 111 | --Testcase 35: 112 | DROP USER MAPPING FOR public SERVER dynamodb_server; 113 | --Testcase 36: 114 | CREATE USER MAPPING FOR public SERVER dynamodb_server 115 | OPTIONS (user 'wrong', password 'wrong'); 116 | -- Should fail with an error 117 | --Testcase 37: 118 | INSERT INTO connection_tbl VALUES ('2', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 119 | --Testcase 38: 120 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '2'; 121 | --Testcase 39: 122 | DELETE FROM connection_tbl WHERE artist = '2'; 123 | -- Drop user mapping and create without username and password for public 124 | -- user mapping 125 | --Testcase 40: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 41: 128 | CREATE USER MAPPING FOR public SERVER dynamodb_server; 129 | -- Should fail with an error 130 | --Testcase 42: 131 | INSERT INTO connection_tbl VALUES ('3', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 132 | --Testcase 43: 133 | DELETE FROM connection_tbl WHERE artist = '3'; 134 | 135 | --Testcase 44: 136 | DROP USER MAPPING FOR public SERVER dynamodb_server; 137 | --Testcase 45: 138 | DROP EXTENSION dynamodb_fdw CASCADE; 139 | -------------------------------------------------------------------------------- /sql/17.0/connection_validation.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Create foreign tables and validate 17 | --Testcase 4: 18 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 19 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 20 | 21 | --Testcase 5: 22 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 23 | 24 | 25 | -- Drop foreign table and create it again without partition_key and sort_key 26 | --Testcase 6: 27 | DROP FOREIGN TABLE connection_tbl; 28 | --Testcase 7: 29 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 30 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 33 | -- Should fail with an error 34 | --Testcase 9: 35 | INSERT INTO connection_tbl VALUES ('9', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 36 | --Testcase 10: 37 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '9'; 38 | --Testcase 11: 39 | DELETE FROM connection_tbl WHERE artist = '9'; 40 | --Testcase 12: 41 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 42 | 43 | 44 | -- Drop foreign table and create it again with invalid partition_key and valid sort_key 45 | --Testcase 13: 46 | DROP FOREIGN TABLE connection_tbl; 47 | --Testcase 14: 48 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 49 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'wrong', sort_key 'songtitle'); 50 | --Testcase 15: 51 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 52 | -- Should fail with an error 53 | --Testcase 16: 54 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 55 | --Testcase 17: 56 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 57 | --Testcase 18: 58 | DELETE FROM connection_tbl WHERE artist = '8'; 59 | --Testcase 19: 60 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 61 | 62 | -- Drop foreign table and create it again with valid partition_key and invalid sort_key 63 | --Testcase 20: 64 | DROP FOREIGN TABLE connection_tbl; 65 | --Testcase 21: 66 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 67 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'wrong'); 68 | -- Should fail with an error 69 | --Testcase 22: 70 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 71 | --Testcase 23: 72 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 73 | -- Should fail to update/delete the data with an error 74 | --Testcase 24: 75 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 76 | --Testcase 25: 77 | DELETE FROM connection_tbl WHERE artist = '8'; 78 | --Testcase 26: 79 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 80 | 81 | 82 | -- Alter one of the SERVER option 83 | -- Set correct partition_key and sort_key for dynamodb_server 84 | --Testcase 27: 85 | DROP FOREIGN TABLE connection_tbl; 86 | --Testcase 28: 87 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 88 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 89 | -- Set wrong endpoint for dynamodb_server 90 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint 'http://localhost:6868'); 91 | -- Should fail with an error 92 | --Testcase 29: 93 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 94 | --Testcase 30: 95 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '1'; 96 | --Testcase 31: 97 | DELETE FROM connection_tbl WHERE artist = '1'; 98 | --Testcase 32: 99 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 100 | -- Set correct address for dynamodb_server 101 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint :DYNAMODB_ENDPOINT); 102 | -- Should able to insert the data 103 | --Testcase 33: 104 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 105 | --Testcase 34: 106 | DELETE FROM connection_tbl WHERE artist = '1'; 107 | 108 | 109 | -- Drop user mapping and create with invalid user and password for public 110 | -- user mapping 111 | --Testcase 35: 112 | DROP USER MAPPING FOR public SERVER dynamodb_server; 113 | --Testcase 36: 114 | CREATE USER MAPPING FOR public SERVER dynamodb_server 115 | OPTIONS (user 'wrong', password 'wrong'); 116 | -- Should fail with an error 117 | --Testcase 37: 118 | INSERT INTO connection_tbl VALUES ('2', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 119 | --Testcase 38: 120 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '2'; 121 | --Testcase 39: 122 | DELETE FROM connection_tbl WHERE artist = '2'; 123 | -- Drop user mapping and create without username and password for public 124 | -- user mapping 125 | --Testcase 40: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 41: 128 | CREATE USER MAPPING FOR public SERVER dynamodb_server; 129 | -- Should fail with an error 130 | --Testcase 42: 131 | INSERT INTO connection_tbl VALUES ('3', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 132 | --Testcase 43: 133 | DELETE FROM connection_tbl WHERE artist = '3'; 134 | 135 | --Testcase 44: 136 | DROP USER MAPPING FOR public SERVER dynamodb_server; 137 | --Testcase 45: 138 | DROP EXTENSION dynamodb_fdw CASCADE; 139 | -------------------------------------------------------------------------------- /expected/17.0/dynamodb_fdw.out: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | --Testcase 1: 3 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 4 | --Testcase 2: 5 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 6 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 7 | -- Get version 8 | --Testcase 42: 9 | SELECT * FROM public.dynamodb_fdw_version(); 10 | dynamodb_fdw_version 11 | ---------------------- 12 | 10400 13 | (1 row) 14 | 15 | --Testcase 43: 16 | SELECT dynamodb_fdw_version(); 17 | dynamodb_fdw_version 18 | ---------------------- 19 | 10400 20 | (1 row) 21 | 22 | -- ==================================================================== 23 | -- Check that userid to use when querying the remote table is correctly 24 | -- propagated into foreign rels. 25 | -- ==================================================================== 26 | -- create empty_owner without access information to detect incorrect UserID. 27 | --Testcase 3: 28 | CREATE ROLE empty_owner LOGIN SUPERUSER; 29 | --Testcase 4: 30 | SET ROLE empty_owner; 31 | --Testcase 5: 32 | CREATE FOREIGN TABLE example1 (artist text, songtitle text, albumtitle text) 33 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 34 | --Testcase 6: 35 | CREATE VIEW v4 AS SELECT * FROM example1; 36 | -- If undefine user owner, postgres core defaults to using the current user to query. 37 | -- For Foreign Scan, Foreign Modify. 38 | --Testcase 7: 39 | SELECT * FROM v4; 40 | ERROR: user mapping not found for user "empty_owner", server "dynamodb_server" 41 | --Testcase 8: 42 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 43 | ERROR: user mapping not found for user "empty_owner", server "dynamodb_server" 44 | --Testcase 9: 45 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 46 | ERROR: user mapping not found for user "empty_owner", server "dynamodb_server" 47 | --Testcase 10: 48 | DELETE FROM v4; 49 | ERROR: user mapping not found for user "empty_owner", server "dynamodb_server" 50 | --Testcase 11: 51 | CREATE ROLE regress_view_owner_another; 52 | --Testcase 12: 53 | ALTER VIEW v4 OWNER TO regress_view_owner_another; 54 | --Testcase 13: 55 | ALTER FOREIGN TABLE example1 OWNER TO regress_view_owner_another; 56 | --Testcase 14: 57 | GRANT SELECT ON example1 TO regress_view_owner_another; 58 | --Testcase 15: 59 | GRANT INSERT ON example1 TO regress_view_owner_another; 60 | --Testcase 16: 61 | GRANT UPDATE ON example1 TO regress_view_owner_another; 62 | --Testcase 17: 63 | GRANT DELETE ON example1 TO regress_view_owner_another; 64 | -- It fails as expected due to the lack of a user mapping for that user. 65 | -- For Foreign Scan, Foreign Modify. 66 | --Testcase 18: 67 | SELECT * FROM v4; 68 | ERROR: user mapping not found for user "regress_view_owner_another", server "dynamodb_server" 69 | --Testcase 19: 70 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 71 | ERROR: user mapping not found for user "regress_view_owner_another", server "dynamodb_server" 72 | --Testcase 20: 73 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 74 | ERROR: user mapping not found for user "regress_view_owner_another", server "dynamodb_server" 75 | --Testcase 21: 76 | DELETE FROM v4; 77 | ERROR: user mapping not found for user "regress_view_owner_another", server "dynamodb_server" 78 | -- Identify the correct user, but it fails due to the lack access informations. 79 | --Testcase 22: 80 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 81 | -- For Foreign Scan, Foreign Modify. 82 | --Testcase 23: 83 | SELECT * FROM v4; 84 | ERROR: dynamodb_fdw: password is required 85 | DETAIL: Non-superusers must provide a password in the user mapping. 86 | --Testcase 24: 87 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 88 | ERROR: dynamodb_fdw: password is required 89 | DETAIL: Non-superusers must provide a password in the user mapping. 90 | --Testcase 25: 91 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 92 | ERROR: dynamodb_fdw: password is required 93 | DETAIL: Non-superusers must provide a password in the user mapping. 94 | --Testcase 26: 95 | DELETE FROM v4; 96 | ERROR: dynamodb_fdw: password is required 97 | DETAIL: Non-superusers must provide a password in the user mapping. 98 | --Testcase 27: 99 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 100 | -- Should not get that error once a user mapping is created and have enough information. 101 | --Testcase 28: 102 | CREATE USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 103 | -- For Foreign Scan, Foreign Modify. 104 | --Testcase 29: 105 | SELECT * FROM v4; 106 | artist | songtitle | albumtitle 107 | -----------------+---------------------+------------------ 108 | 9 | SomE oNe LiKE yOu | RECORD INSERTED 109 | Acme Band | Happy Day | Songs About Life 110 | 8 | SomE oNe LiKE yOu | RECORD INSERTED 111 | No One You Know | Call Me Today | Somewhat Famous 112 | No One You Know | Scared of My Shadow | Blue Sky Blues 113 | (5 rows) 114 | 115 | --Testcase 30: 116 | INSERT INTO v4 VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 117 | --Testcase 31: 118 | UPDATE v4 SET albumtitle = 'RECORD UPDATED'; 119 | --Testcase 32: 120 | DELETE FROM v4; 121 | -- Clean 122 | --Testcase 33: 123 | DROP VIEW v4; 124 | --Testcase 34: 125 | DROP USER MAPPING FOR regress_view_owner_another SERVER dynamodb_server; 126 | --Testcase 35: 127 | DROP OWNED BY regress_view_owner_another; 128 | --Testcase 36: 129 | DROP OWNED BY empty_owner; 130 | --Testcase 37: 131 | DROP ROLE regress_view_owner_another; 132 | --Testcase 38: 133 | -- current user cannot be dropped 134 | --Testcase 39: 135 | RESET ROLE; 136 | --Testcase 40: 137 | DROP ROLE empty_owner; 138 | --Testcase 41: 139 | DROP EXTENSION dynamodb_fdw CASCADE; 140 | NOTICE: drop cascades to server dynamodb_server 141 | -------------------------------------------------------------------------------- /sql/13.15/connection_validation.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Create foreign tables and validate 17 | --Testcase 4: 18 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 19 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 20 | 21 | --Testcase 5: 22 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 23 | 24 | 25 | -- Drop foreign table and create it again without partition_key and sort_key 26 | --Testcase 6: 27 | DROP FOREIGN TABLE connection_tbl; 28 | --Testcase 7: 29 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 30 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 33 | -- Should fail with an error 34 | --Testcase 9: 35 | INSERT INTO connection_tbl VALUES ('9', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 36 | --Testcase 10: 37 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '9'; 38 | --Testcase 11: 39 | DELETE FROM connection_tbl WHERE artist = '9'; 40 | --Testcase 12: 41 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 42 | 43 | 44 | -- Drop foreign table and create it again with invalid partition_key and valid sort_key 45 | --Testcase 13: 46 | DROP FOREIGN TABLE connection_tbl; 47 | --Testcase 14: 48 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 49 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'wrong', sort_key 'songtitle'); 50 | --Testcase 15: 51 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 52 | -- Should fail with an error 53 | --Testcase 16: 54 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 55 | --Testcase 17: 56 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 57 | --Testcase 18: 58 | DELETE FROM connection_tbl WHERE artist = '8'; 59 | --Testcase 19: 60 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 61 | 62 | -- Drop foreign table and create it again with valid partition_key and invalid sort_key 63 | --Testcase 20: 64 | DROP FOREIGN TABLE connection_tbl; 65 | --Testcase 21: 66 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 67 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'wrong'); 68 | -- Should fail with an error 69 | --Testcase 22: 70 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 71 | --Testcase 23: 72 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 73 | -- Should fail to update/delete the data with an error 74 | --Testcase 24: 75 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 76 | --Testcase 25: 77 | DELETE FROM connection_tbl WHERE artist = '8'; 78 | --Testcase 26: 79 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 80 | 81 | 82 | -- Alter one of the SERVER option 83 | -- Set correct partition_key and sort_key for dynamodb_server 84 | --Testcase 27: 85 | DROP FOREIGN TABLE connection_tbl; 86 | --Testcase 28: 87 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 88 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 89 | -- Set wrong endpoint for dynamodb_server 90 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint 'http://localhost:6868'); 91 | -- Should fail with an error 92 | --Testcase 29: 93 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 94 | --Testcase 30: 95 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '1'; 96 | --Testcase 31: 97 | DELETE FROM connection_tbl WHERE artist = '1'; 98 | --Testcase 32: 99 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 100 | -- Set correct address for dynamodb_server 101 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint :DYNAMODB_ENDPOINT); 102 | -- Should able to insert the data 103 | --Testcase 33: 104 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 105 | --Testcase 34: 106 | DELETE FROM connection_tbl WHERE artist = '1'; 107 | 108 | 109 | -- Drop user mapping and create with invalid user and password for public 110 | -- user mapping 111 | --Testcase 35: 112 | DROP USER MAPPING FOR public SERVER dynamodb_server; 113 | --Testcase 36: 114 | CREATE USER MAPPING FOR public SERVER dynamodb_server 115 | OPTIONS (user 'wrong', password 'wrong'); 116 | -- Should fail with an error 117 | --Testcase 37: 118 | INSERT INTO connection_tbl VALUES ('2', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 119 | --Testcase 38: 120 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '2'; 121 | --Testcase 39: 122 | DELETE FROM connection_tbl WHERE artist = '2'; 123 | -- Drop user mapping and create without username and password for public 124 | -- user mapping 125 | --Testcase 40: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 41: 128 | CREATE USER MAPPING FOR public SERVER dynamodb_server; 129 | -- Should fail with an error 130 | --Testcase 42: 131 | INSERT INTO connection_tbl VALUES ('3', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 132 | --Testcase 43: 133 | DELETE FROM connection_tbl WHERE artist = '3'; 134 | 135 | --Testcase 44: 136 | DROP USER MAPPING FOR public SERVER dynamodb_server; 137 | --Testcase 45: 138 | DROP EXTENSION dynamodb_fdw CASCADE; 139 | -------------------------------------------------------------------------------- /sql/14.12/connection_validation.sql: -------------------------------------------------------------------------------- 1 | \set ECHO none 2 | \ir sql/parameters.conf 3 | \set ECHO all 4 | 5 | 6 | --Testcase 1: 7 | CREATE EXTENSION IF NOT EXISTS dynamodb_fdw; 8 | --Testcase 2: 9 | CREATE SERVER dynamodb_server FOREIGN DATA WRAPPER dynamodb_fdw 10 | OPTIONS (endpoint :DYNAMODB_ENDPOINT); 11 | --Testcase 3: 12 | CREATE USER MAPPING FOR public SERVER dynamodb_server 13 | OPTIONS (user :DYNAMODB_USER, password :DYNAMODB_PASSWORD); 14 | 15 | 16 | -- Create foreign tables and validate 17 | --Testcase 4: 18 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 19 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 20 | 21 | --Testcase 5: 22 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 23 | 24 | 25 | -- Drop foreign table and create it again without partition_key and sort_key 26 | --Testcase 6: 27 | DROP FOREIGN TABLE connection_tbl; 28 | --Testcase 7: 29 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 30 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl'); 31 | --Testcase 8: 32 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 33 | -- Should fail with an error 34 | --Testcase 9: 35 | INSERT INTO connection_tbl VALUES ('9', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 36 | --Testcase 10: 37 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '9'; 38 | --Testcase 11: 39 | DELETE FROM connection_tbl WHERE artist = '9'; 40 | --Testcase 12: 41 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 42 | 43 | 44 | -- Drop foreign table and create it again with invalid partition_key and valid sort_key 45 | --Testcase 13: 46 | DROP FOREIGN TABLE connection_tbl; 47 | --Testcase 14: 48 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 49 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'wrong', sort_key 'songtitle'); 50 | --Testcase 15: 51 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 52 | -- Should fail with an error 53 | --Testcase 16: 54 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 55 | --Testcase 17: 56 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 57 | --Testcase 18: 58 | DELETE FROM connection_tbl WHERE artist = '8'; 59 | --Testcase 19: 60 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 61 | 62 | -- Drop foreign table and create it again with valid partition_key and invalid sort_key 63 | --Testcase 20: 64 | DROP FOREIGN TABLE connection_tbl; 65 | --Testcase 21: 66 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 67 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'wrong'); 68 | -- Should fail with an error 69 | --Testcase 22: 70 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 71 | --Testcase 23: 72 | INSERT INTO connection_tbl VALUES ('8', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 73 | -- Should fail to update/delete the data with an error 74 | --Testcase 24: 75 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '8'; 76 | --Testcase 25: 77 | DELETE FROM connection_tbl WHERE artist = '8'; 78 | --Testcase 26: 79 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 80 | 81 | 82 | -- Alter one of the SERVER option 83 | -- Set correct partition_key and sort_key for dynamodb_server 84 | --Testcase 27: 85 | DROP FOREIGN TABLE connection_tbl; 86 | --Testcase 28: 87 | CREATE FOREIGN TABLE connection_tbl (artist text, songtitle text, albumtitle text) 88 | SERVER dynamodb_server OPTIONS (table_name 'connection_tbl', partition_key 'artist', sort_key 'songtitle'); 89 | -- Set wrong endpoint for dynamodb_server 90 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint 'http://localhost:6868'); 91 | -- Should fail with an error 92 | --Testcase 29: 93 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 94 | --Testcase 30: 95 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '1'; 96 | --Testcase 31: 97 | DELETE FROM connection_tbl WHERE artist = '1'; 98 | --Testcase 32: 99 | SELECT artist, songtitle, albumtitle FROM connection_tbl ORDER BY 1, 2; 100 | -- Set correct address for dynamodb_server 101 | ALTER SERVER dynamodb_server OPTIONS (SET endpoint :DYNAMODB_ENDPOINT); 102 | -- Should able to insert the data 103 | --Testcase 33: 104 | INSERT INTO connection_tbl VALUES ('1', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 105 | --Testcase 34: 106 | DELETE FROM connection_tbl WHERE artist = '1'; 107 | 108 | 109 | -- Drop user mapping and create with invalid user and password for public 110 | -- user mapping 111 | --Testcase 35: 112 | DROP USER MAPPING FOR public SERVER dynamodb_server; 113 | --Testcase 36: 114 | CREATE USER MAPPING FOR public SERVER dynamodb_server 115 | OPTIONS (user 'wrong', password 'wrong'); 116 | -- Should fail with an error 117 | --Testcase 37: 118 | INSERT INTO connection_tbl VALUES ('2', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 119 | --Testcase 38: 120 | UPDATE connection_tbl SET albumtitle = 'RECORD UPDATED' WHERE artist = '2'; 121 | --Testcase 39: 122 | DELETE FROM connection_tbl WHERE artist = '2'; 123 | -- Drop user mapping and create without username and password for public 124 | -- user mapping 125 | --Testcase 40: 126 | DROP USER MAPPING FOR public SERVER dynamodb_server; 127 | --Testcase 41: 128 | CREATE USER MAPPING FOR public SERVER dynamodb_server; 129 | -- Should fail with an error 130 | --Testcase 42: 131 | INSERT INTO connection_tbl VALUES ('3', 'SomE oNe LiKE yOu', 'RECORD INSERTED'); 132 | --Testcase 43: 133 | DELETE FROM connection_tbl WHERE artist = '3'; 134 | 135 | --Testcase 44: 136 | DROP USER MAPPING FOR public SERVER dynamodb_server; 137 | --Testcase 45: 138 | DROP EXTENSION dynamodb_fdw CASCADE; 139 | -------------------------------------------------------------------------------- /dynamodb_fdw.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * dynamodb_fdw.c 4 | * FDW routines for dynamodb_fdw 5 | * 6 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 7 | * 8 | * IDENTIFICATION 9 | * contrib/dynamodb_fdw/dynamodb_fdw.c 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | 14 | #include "postgres.h" 15 | #include 16 | 17 | #include "access/htup_details.h" 18 | #include "access/sysattr.h" 19 | #include "access/table.h" 20 | #include "catalog/pg_class.h" 21 | #include "commands/defrem.h" 22 | #include "commands/explain.h" 23 | #include "commands/vacuum.h" 24 | #include "foreign/fdwapi.h" 25 | #include "funcapi.h" 26 | #include "miscadmin.h" 27 | #include "nodes/makefuncs.h" 28 | #include "nodes/nodeFuncs.h" 29 | #include "optimizer/clauses.h" 30 | #include "optimizer/cost.h" 31 | #include "optimizer/optimizer.h" 32 | #include "optimizer/pathnode.h" 33 | #include "optimizer/paths.h" 34 | #include "optimizer/planmain.h" 35 | #include "optimizer/restrictinfo.h" 36 | #include "optimizer/tlist.h" 37 | #include "parser/parsetree.h" 38 | #include "storage/ipc.h" 39 | #include "utils/builtins.h" 40 | #include "utils/float.h" 41 | #include "utils/guc.h" 42 | #include "utils/lsyscache.h" 43 | #include "utils/memutils.h" 44 | #include "utils/rel.h" 45 | #include "utils/sampling.h" 46 | #include "utils/selfuncs.h" 47 | #include "dynamodb_fdw.h" 48 | #include "storage/ipc.h" 49 | 50 | PG_MODULE_MAGIC; 51 | 52 | void _PG_init(void); 53 | extern void dynamodb_init(); 54 | extern void dynamodb_shutdown(); 55 | 56 | /* 57 | * FDW callback routines 58 | */ 59 | extern void dynamodbGetForeignRelSize(PlannerInfo *root, 60 | RelOptInfo *baserel, 61 | Oid foreigntableid); 62 | extern void dynamodbGetForeignPaths(PlannerInfo *root, 63 | RelOptInfo *baserel, 64 | Oid foreigntableid); 65 | extern ForeignScan *dynamodbGetForeignPlan(PlannerInfo *root, 66 | RelOptInfo *foreignrel, 67 | Oid foreigntableid, 68 | ForeignPath *best_path, 69 | List *tlist, 70 | List *scan_clauses, 71 | Plan *outer_plan); 72 | extern void dynamodbBeginForeignScan(ForeignScanState *node, int eflags); 73 | extern TupleTableSlot *dynamodbIterateForeignScan(ForeignScanState *node); 74 | extern void dynamodbReScanForeignScan(ForeignScanState *node); 75 | extern void dynamodbEndForeignScan(ForeignScanState *node); 76 | extern void dynamodbAddForeignUpdateTargets( 77 | #if (PG_VERSION_NUM >= 140000) 78 | PlannerInfo *root, 79 | Index rtindex, 80 | #else 81 | Query *parsetree, 82 | #endif 83 | RangeTblEntry *target_rte, 84 | Relation target_relation); 85 | extern List *dynamodbPlanForeignModify(PlannerInfo *root, 86 | ModifyTable *plan, 87 | Index resultRelation, 88 | int subplan_index); 89 | extern void dynamodbBeginForeignModify(ModifyTableState *mtstate, 90 | ResultRelInfo *resultRelInfo, 91 | List *fdw_private, 92 | int subplan_index, 93 | int eflags); 94 | extern TupleTableSlot *execute_foreign_modify(EState *estate, 95 | ResultRelInfo *resultRelInfo, 96 | CmdType operation, 97 | TupleTableSlot *slot, 98 | TupleTableSlot *planSlot); 99 | extern TupleTableSlot *dynamodbExecForeignInsert(EState *estate, 100 | ResultRelInfo *resultRelInfo, 101 | TupleTableSlot *slot, 102 | TupleTableSlot *planSlot); 103 | extern TupleTableSlot *dynamodbExecForeignUpdate(EState *estate, 104 | ResultRelInfo *resultRelInfo, 105 | TupleTableSlot *slot, 106 | TupleTableSlot *planSlot); 107 | extern TupleTableSlot *dynamodbExecForeignDelete(EState *estate, 108 | ResultRelInfo *resultRelInfo, 109 | TupleTableSlot *slot, 110 | TupleTableSlot *planSlot); 111 | extern void dynamodbEndForeignModify(EState *estate, 112 | ResultRelInfo *resultRelInfo); 113 | 114 | extern void dynamodbExplainForeignScan(ForeignScanState *node, 115 | ExplainState *es); 116 | extern void dynamodbExplainForeignModify(ModifyTableState *mtstate, 117 | ResultRelInfo *rinfo, 118 | List *fdw_private, 119 | int subplan_index, 120 | ExplainState *es); 121 | extern void dynamodbBeginForeignInsert(ModifyTableState *mtstate, 122 | ResultRelInfo *resultRelInfo); 123 | extern void dynamodbEndForeignInsert(EState *estate, 124 | ResultRelInfo *resultRelInfo); 125 | 126 | void 127 | _PG_init(void) 128 | { 129 | dynamodb_init(); 130 | on_proc_exit(&dynamodb_shutdown, PointerGetDatum(NULL)); 131 | } 132 | 133 | 134 | PG_FUNCTION_INFO_V1(dynamodb_fdw_version); 135 | 136 | Datum 137 | dynamodb_fdw_version(PG_FUNCTION_ARGS) 138 | { 139 | PG_RETURN_INT32(CODE_VERSION); 140 | } 141 | 142 | PG_FUNCTION_INFO_V1(dynamodb_fdw_handler); 143 | 144 | /* 145 | * Foreign-data wrapper handler function: return a struct with pointers 146 | * to my callback routines. 147 | */ 148 | Datum 149 | dynamodb_fdw_handler(PG_FUNCTION_ARGS) 150 | { 151 | FdwRoutine *routine = makeNode(FdwRoutine); 152 | 153 | /* Functions for scanning foreign tables */ 154 | routine->GetForeignRelSize = dynamodbGetForeignRelSize; 155 | routine->GetForeignPaths = dynamodbGetForeignPaths; 156 | routine->GetForeignPlan = dynamodbGetForeignPlan; 157 | routine->BeginForeignScan = dynamodbBeginForeignScan; 158 | routine->IterateForeignScan = dynamodbIterateForeignScan; 159 | routine->ReScanForeignScan = dynamodbReScanForeignScan; 160 | routine->EndForeignScan = dynamodbEndForeignScan; 161 | 162 | /* Functions for updating foreign tables */ 163 | routine->AddForeignUpdateTargets = dynamodbAddForeignUpdateTargets; 164 | routine->PlanForeignModify = dynamodbPlanForeignModify; 165 | routine->BeginForeignModify = dynamodbBeginForeignModify; 166 | routine->ExecForeignInsert = dynamodbExecForeignInsert; 167 | routine->ExecForeignUpdate = dynamodbExecForeignUpdate; 168 | routine->ExecForeignDelete = dynamodbExecForeignDelete; 169 | routine->EndForeignModify = dynamodbEndForeignModify; 170 | routine->BeginForeignInsert = dynamodbBeginForeignInsert; 171 | routine->EndForeignInsert = dynamodbEndForeignInsert; 172 | 173 | /* Support functions for EXPLAIN */ 174 | routine->ExplainForeignScan = dynamodbExplainForeignScan; 175 | routine->ExplainForeignModify = dynamodbExplainForeignModify; 176 | 177 | PG_RETURN_POINTER(routine); 178 | } 179 | -------------------------------------------------------------------------------- /option.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * option.c 4 | * FDW option handling for dynamodb_fdw 5 | * 6 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 7 | * 8 | * IDENTIFICATION 9 | * contrib/dynamodb_fdw/option.c 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | #include "postgres.h" 14 | 15 | #include "access/reloptions.h" 16 | #include "catalog/pg_foreign_server.h" 17 | #include "catalog/pg_foreign_table.h" 18 | #include "catalog/pg_user_mapping.h" 19 | #include "commands/defrem.h" 20 | #include "commands/extension.h" 21 | #include "dynamodb_fdw.h" 22 | #include "miscadmin.h" 23 | #include "utils/builtins.h" 24 | #include "utils/varlena.h" 25 | #include "utils/lsyscache.h" 26 | 27 | /* 28 | * Describes the valid options for objects that use this wrapper. 29 | */ 30 | struct DynamodbFdwOption 31 | { 32 | const char *optname; 33 | Oid optcontext; /* Oid of catalog in which option may appear */ 34 | }; 35 | 36 | /* 37 | * Helper functions 38 | */ 39 | static bool is_valid_option(const char *option, Oid context); 40 | /* 41 | * Valid options for dynamodb_fdw. 42 | */ 43 | 44 | static struct DynamodbFdwOption valid_options[] = 45 | { 46 | /* Connection options */ 47 | {"endpoint", ForeignServerRelationId}, 48 | {"partition_key", ForeignTableRelationId}, 49 | {"sort_key", ForeignTableRelationId}, 50 | {"user", UserMappingRelationId}, 51 | {"password", UserMappingRelationId}, 52 | {"table_name", ForeignTableRelationId}, 53 | {"column_name", AttributeRelationId}, 54 | /* Sentinel */ 55 | {NULL, InvalidOid} 56 | }; 57 | 58 | extern Datum dynamodb_fdw_validator(PG_FUNCTION_ARGS); 59 | 60 | PG_FUNCTION_INFO_V1(dynamodb_fdw_validator); 61 | /* 62 | * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, 63 | * USER MAPPING or FOREIGN TABLE that uses dynamodb_fdw. 64 | * 65 | * Raise an ERROR if the option or its value is considered invalid. 66 | */ 67 | Datum 68 | dynamodb_fdw_validator(PG_FUNCTION_ARGS) 69 | { 70 | List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); 71 | Oid catalog = PG_GETARG_OID(1); 72 | ListCell *cell; 73 | /* 74 | * Check that only options supported by dynamodb_fdw, and allowed for the 75 | * current object type, are given. 76 | */ 77 | foreach(cell, options_list) 78 | { 79 | DefElem *def = (DefElem *) lfirst(cell); 80 | 81 | if (!is_valid_option(def->defname, catalog)) 82 | { 83 | struct DynamodbFdwOption *opt; 84 | #if (PG_VERSION_NUM >= 160000) 85 | /* 86 | * Unknown option specified, complain about it. Provide a hint 87 | * with a valid option that looks similar, if there is one. 88 | */ 89 | const char *closest_match; 90 | ClosestMatchState match_state; 91 | bool has_valid_options = false; 92 | initClosestMatch(&match_state, def->defname, 4); 93 | for (opt = valid_options; opt->optname; opt++) 94 | { 95 | if (catalog == opt->optcontext) 96 | { 97 | has_valid_options = true; 98 | updateClosestMatch(&match_state, opt->optname); 99 | } 100 | } 101 | 102 | closest_match = getClosestMatch(&match_state); 103 | ereport(ERROR, 104 | (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), 105 | errmsg("dynamodb_fdw: invalid option \"%s\"", def->defname), 106 | has_valid_options ? closest_match ? 107 | errhint("Perhaps you meant the option \"%s\".", 108 | closest_match) : 0 : 109 | errhint("There are no valid options in this context."))); 110 | #else 111 | /* 112 | * Unknown option specified, complain about it. Provide a hint 113 | * with list of valid options for the object. 114 | */ 115 | StringInfoData buf; 116 | 117 | initStringInfo(&buf); 118 | for (opt = valid_options; opt->optname; opt++) 119 | { 120 | if (catalog == opt->optcontext) 121 | appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", 122 | opt->optname); 123 | } 124 | 125 | ereport(ERROR, 126 | (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), 127 | errmsg("dynamodb_fdw: invalid option \"%s\"", def->defname), 128 | buf.len > 0 129 | ? errhint("Valid options in this context are: %s", 130 | buf.data) 131 | : errhint("There are no valid options in this context."))); 132 | #endif 133 | } 134 | } 135 | PG_RETURN_VOID(); 136 | } 137 | /* 138 | * Check whether the given option is one of the valid dynamodb_fdw options. 139 | * context is the Oid of the catalog holding the object the option is for. 140 | */ 141 | static bool is_valid_option(const char *option, Oid context) 142 | { 143 | struct DynamodbFdwOption *opt; 144 | 145 | for (opt = valid_options; opt->optname; opt++) 146 | { 147 | if (context == opt->optcontext && strcmp(opt->optname, option) == 0) 148 | return true; 149 | } 150 | return false; 151 | } 152 | /* 153 | * Fetch the options for a dynamodb_fdw foreign table. 154 | */ 155 | dynamodb_opt *dynamodb_get_options(Oid foreignoid, Oid userid) 156 | { 157 | UserMapping *f_mapping; 158 | ForeignTable *f_table = NULL; 159 | ForeignServer *f_server = NULL; 160 | List *options; 161 | ListCell *lc; 162 | dynamodb_opt *opt; 163 | 164 | opt = (dynamodb_opt *) palloc0(sizeof(dynamodb_opt)); 165 | 166 | /* 167 | * Extract options from FDW objects. 168 | */ 169 | PG_TRY(); 170 | { 171 | f_table = GetForeignTable(foreignoid); 172 | f_server = GetForeignServer(f_table->serverid); 173 | } 174 | PG_CATCH(); 175 | { 176 | f_table = NULL; 177 | f_server = GetForeignServer(foreignoid); 178 | } 179 | PG_END_TRY(); 180 | 181 | options = NIL; 182 | if (f_table) 183 | options = list_concat(options, f_table->options); 184 | options = list_concat(options, f_server->options); 185 | 186 | f_mapping = GetUserMapping(userid, f_server->serverid); 187 | options = list_concat(options, f_mapping->options); 188 | 189 | /* Loop through the options, and get the server/port */ 190 | foreach(lc, options) 191 | { 192 | DefElem *def = (DefElem *) lfirst(lc); 193 | 194 | if (strcmp(def->defname, "endpoint") == 0) 195 | opt->svr_endpoint = defGetString(def); 196 | 197 | if (strcmp(def->defname, "user") == 0) 198 | opt->svr_username = defGetString(def); 199 | 200 | if (strcmp(def->defname, "password") == 0) 201 | opt->svr_password = defGetString(def); 202 | 203 | if (strcmp(def->defname, "partition_key") == 0) 204 | opt->svr_partition_key = defGetString(def); 205 | 206 | if (strcmp(def->defname, "sort_key") == 0) 207 | opt->svr_sort_key = defGetString(def); 208 | } 209 | 210 | /* Default values, if required */ 211 | if (!opt->svr_endpoint) 212 | opt->svr_endpoint = "http://localhost:8000"; 213 | 214 | return opt; 215 | } 216 | -------------------------------------------------------------------------------- /shippable.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * shippable.c 4 | * Determine which database objects are shippable to a remote server. 5 | * 6 | * We need to determine whether particular functions, operators, and indeed 7 | * data types are shippable to a remote server for execution --- that is, 8 | * do they exist and have the same behavior remotely as they do locally? 9 | * Built-in objects are generally considered shippable. Other objects can 10 | * be shipped if they are declared as such by the user. 11 | * 12 | * Note: there are additional filter rules that prevent shipping mutable 13 | * functions or functions using nonportable collations. Those considerations 14 | * need not be accounted for here. 15 | * 16 | * Portions Copyright (c) 2021, TOSHIBA CORPORATION 17 | * 18 | * IDENTIFICATION 19 | * contrib/dynamodb_fdw/shippable.c 20 | * 21 | *------------------------------------------------------------------------- 22 | */ 23 | 24 | #include "postgres.h" 25 | 26 | #include "access/transam.h" 27 | #include "catalog/dependency.h" 28 | #include "dynamodb_fdw.h" 29 | #include "utils/hsearch.h" 30 | #include "utils/inval.h" 31 | #include "utils/syscache.h" 32 | 33 | /* Hash table for caching the results of shippability lookups */ 34 | static HTAB *ShippableCacheHash = NULL; 35 | 36 | /* 37 | * Hash key for shippability lookups. We include the FDW server OID because 38 | * decisions may differ per-server. Otherwise, objects are identified by 39 | * their (local!) OID and catalog OID. 40 | */ 41 | typedef struct 42 | { 43 | /* XXX we assume this struct contains no padding bytes */ 44 | Oid objid; /* function/operator/type OID */ 45 | Oid classid; /* OID of its catalog (pg_proc, etc) */ 46 | Oid serverid; /* FDW server we are concerned with */ 47 | } ShippableCacheKey; 48 | 49 | typedef struct 50 | { 51 | ShippableCacheKey key; /* hash key - must be first */ 52 | bool shippable; 53 | } ShippableCacheEntry; 54 | 55 | 56 | /* 57 | * Flush cache entries when pg_foreign_server is updated. 58 | * 59 | * We do this because of the possibility of ALTER SERVER being used to change 60 | * a server's extensions option. We do not currently bother to check whether 61 | * objects' extension membership changes once a shippability decision has been 62 | * made for them, however. 63 | */ 64 | static void 65 | InvalidateShippableCacheCallback(Datum arg, int cacheid, uint32 hashvalue) 66 | { 67 | HASH_SEQ_STATUS status; 68 | ShippableCacheEntry *entry; 69 | 70 | /* 71 | * In principle we could flush only cache entries relating to the 72 | * pg_foreign_server entry being outdated; but that would be more 73 | * complicated, and it's probably not worth the trouble. So for now, just 74 | * flush all entries. 75 | */ 76 | hash_seq_init(&status, ShippableCacheHash); 77 | while ((entry = (ShippableCacheEntry *) hash_seq_search(&status)) != NULL) 78 | { 79 | if (hash_search(ShippableCacheHash, 80 | #if (PG_VERSION_NUM >= 160000) 81 | &entry->key, 82 | #else 83 | (void *) &entry->key, 84 | #endif 85 | HASH_REMOVE, 86 | NULL) == NULL) 87 | elog(ERROR, "dynamodb_fdw: hash table corrupted"); 88 | } 89 | } 90 | 91 | /* 92 | * Initialize the backend-lifespan cache of shippability decisions. 93 | */ 94 | static void 95 | InitializeShippableCache(void) 96 | { 97 | HASHCTL ctl; 98 | 99 | /* Create the hash table. */ 100 | #if PG_VERSION_NUM < 140000 101 | MemSet(&ctl, 0, sizeof(ctl)); 102 | #endif 103 | ctl.keysize = sizeof(ShippableCacheKey); 104 | ctl.entrysize = sizeof(ShippableCacheEntry); 105 | ShippableCacheHash = 106 | hash_create("Shippability cache", 256, &ctl, HASH_ELEM | HASH_BLOBS); 107 | 108 | /* Set up invalidation callback on pg_foreign_server. */ 109 | CacheRegisterSyscacheCallback(FOREIGNSERVEROID, 110 | InvalidateShippableCacheCallback, 111 | (Datum) 0); 112 | } 113 | 114 | /* 115 | * Returns true if given object (operator/function/type) is shippable 116 | * according to the server options. 117 | * 118 | * Right now "shippability" is exclusively a function of whether the object 119 | * belongs to an extension declared by the user. In the future we could 120 | * additionally have a list of functions/operators declared one at a time. 121 | */ 122 | static bool 123 | dynamodb_lookup_shippable(Oid objectId, Oid classId, DynamoDBFdwRelationInfo *fpinfo) 124 | { 125 | Oid extensionOid; 126 | 127 | /* 128 | * Is object a member of some extension? (Note: this is a fairly 129 | * expensive lookup, which is why we try to cache the results.) 130 | */ 131 | extensionOid = getExtensionOfObject(classId, objectId); 132 | 133 | /* If so, is that extension in fpinfo->shippable_extensions? */ 134 | if (OidIsValid(extensionOid) && 135 | list_member_oid(fpinfo->shippable_extensions, extensionOid)) 136 | return true; 137 | 138 | return false; 139 | } 140 | 141 | /* 142 | * Return true if given object is one of PostgreSQL's built-in objects. 143 | * 144 | * We use FirstGenbkiObjectId as the cutoff, so that we only consider 145 | * objects with hand-assigned OIDs to be "built in", not for instance any 146 | * function or type defined in the information_schema. 147 | * 148 | * Our constraints for dealing with types are tighter than they are for 149 | * functions or operators: we want to accept only types that are in pg_catalog, 150 | * else deparse_type_name might incorrectly fail to schema-qualify their names. 151 | * Thus we must exclude information_schema types. 152 | * 153 | * XXX there is a problem with this, which is that the set of built-in 154 | * objects expands over time. Something that is built-in to us might not 155 | * be known to the remote server, if it's of an older version. But keeping 156 | * track of that would be a huge exercise. 157 | */ 158 | bool 159 | dynamodb_is_builtin(Oid objectId) 160 | { 161 | return (objectId < FirstGenbkiObjectId); 162 | } 163 | 164 | /* 165 | * dynamodb_is_shippable 166 | * 167 | * Is this object (function/operator/type) shippable to foreign server? 168 | */ 169 | bool 170 | dynamodb_is_shippable(Oid objectId, Oid classId, DynamoDBFdwRelationInfo *fpinfo) 171 | { 172 | ShippableCacheKey key; 173 | ShippableCacheEntry *entry; 174 | 175 | /* Built-in objects are presumed shippable. */ 176 | if (dynamodb_is_builtin(objectId)) 177 | return true; 178 | 179 | /* Otherwise, give up if user hasn't specified any shippable extensions. */ 180 | if (fpinfo->shippable_extensions == NIL) 181 | return false; 182 | 183 | /* Initialize cache if first time through. */ 184 | if (!ShippableCacheHash) 185 | InitializeShippableCache(); 186 | 187 | /* Set up cache hash key */ 188 | key.objid = objectId; 189 | key.classid = classId; 190 | key.serverid = fpinfo->server->serverid; 191 | 192 | /* See if we already cached the result. */ 193 | entry = (ShippableCacheEntry *) 194 | #if (PG_VERSION_NUM >= 160000) 195 | hash_search(ShippableCacheHash, &key, HASH_FIND, NULL); 196 | #else 197 | hash_search(ShippableCacheHash, 198 | (void *) &key, 199 | HASH_FIND, 200 | NULL); 201 | #endif 202 | 203 | if (!entry) 204 | { 205 | /* Not found in cache, so perform shippability lookup. */ 206 | bool shippable = dynamodb_lookup_shippable(objectId, classId, fpinfo); 207 | 208 | /* 209 | * Don't create a new hash entry until *after* we have the shippable 210 | * result in hand, as the underlying catalog lookups might trigger a 211 | * cache invalidation. 212 | */ 213 | entry = (ShippableCacheEntry *) 214 | #if (PG_VERSION_NUM >= 160000) 215 | hash_search(ShippableCacheHash, &key, HASH_ENTER, NULL); 216 | #else 217 | hash_search(ShippableCacheHash, 218 | (void *) &key, 219 | HASH_ENTER, 220 | NULL); 221 | #endif 222 | entry->shippable = shippable; 223 | } 224 | 225 | return entry->shippable; 226 | } 227 | -------------------------------------------------------------------------------- /jansson/hashtable_seed.c: -------------------------------------------------------------------------------- 1 | /* Generate sizeof(uint32_t) bytes of as random data as possible to seed 2 | the hash function. 3 | */ 4 | 5 | #ifdef HAVE_CONFIG_H 6 | #include 7 | #endif 8 | 9 | #include 10 | #include 11 | 12 | #ifdef HAVE_STDINT_H 13 | #include 14 | #endif 15 | 16 | #ifdef HAVE_FCNTL_H 17 | #include 18 | #endif 19 | 20 | #ifdef HAVE_SCHED_H 21 | #include 22 | #endif 23 | 24 | #ifdef HAVE_UNISTD_H 25 | #include 26 | #endif 27 | 28 | #ifdef HAVE_SYS_STAT_H 29 | #include 30 | #endif 31 | 32 | #ifdef HAVE_SYS_TIME_H 33 | #include 34 | #endif 35 | 36 | #ifdef HAVE_SYS_TYPES_H 37 | #include 38 | #endif 39 | 40 | #if defined(_WIN32) 41 | /* For GetModuleHandle(), GetProcAddress() and GetCurrentProcessId() */ 42 | #include 43 | #endif 44 | 45 | #include "jansson.h" 46 | 47 | #if ((!defined(_WIN32) && defined(USE_URANDOM)) || (defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI))) 48 | static uint32_t buf_to_uint32(char *data) { 49 | size_t i; 50 | uint32_t result = 0; 51 | 52 | for (i = 0; i < sizeof(uint32_t); i++) 53 | result = (result << 8) | (unsigned char)data[i]; 54 | 55 | return result; 56 | } 57 | 58 | #endif 59 | 60 | /* /dev/urandom */ 61 | #if !defined(_WIN32) && defined(USE_URANDOM) 62 | static int seed_from_urandom(uint32_t *seed) { 63 | /* Use unbuffered I/O if we have open(), close() and read(). Otherwise 64 | fall back to fopen() */ 65 | 66 | char data[sizeof(uint32_t)]; 67 | int ok; 68 | 69 | #if defined(HAVE_OPEN) && defined(HAVE_CLOSE) && defined(HAVE_READ) 70 | int urandom; 71 | urandom = open("/dev/urandom", O_RDONLY); 72 | if (urandom == -1) 73 | return 1; 74 | 75 | ok = read(urandom, data, sizeof(uint32_t)) == sizeof(uint32_t); 76 | close(urandom); 77 | #else 78 | FILE *urandom; 79 | 80 | urandom = fopen("/dev/urandom", "rb"); 81 | if (!urandom) 82 | return 1; 83 | 84 | ok = fread(data, 1, sizeof(uint32_t), urandom) == sizeof(uint32_t); 85 | fclose(urandom); 86 | #endif 87 | 88 | if (!ok) 89 | return 1; 90 | 91 | *seed = buf_to_uint32(data); 92 | return 0; 93 | } 94 | #endif 95 | 96 | /* Windows Crypto API */ 97 | #if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI) 98 | #include 99 | 100 | typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags); 101 | typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer); 102 | typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags); 103 | 104 | static int seed_from_windows_cryptoapi(uint32_t *seed) 105 | { 106 | HINSTANCE hAdvAPI32 = NULL; 107 | CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL; 108 | CRYPTGENRANDOM pCryptGenRandom = NULL; 109 | CRYPTRELEASECONTEXT pCryptReleaseContext = NULL; 110 | HCRYPTPROV hCryptProv = 0; 111 | BYTE data[sizeof(uint32_t)]; 112 | int ok; 113 | 114 | hAdvAPI32 = GetModuleHandle(TEXT("advapi32.dll")); 115 | if(hAdvAPI32 == NULL) 116 | return 1; 117 | 118 | pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32, "CryptAcquireContextA"); 119 | if (!pCryptAcquireContext) 120 | return 1; 121 | 122 | pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32, "CryptGenRandom"); 123 | if (!pCryptGenRandom) 124 | return 1; 125 | 126 | pCryptReleaseContext = (CRYPTRELEASECONTEXT)GetProcAddress(hAdvAPI32, "CryptReleaseContext"); 127 | if (!pCryptReleaseContext) 128 | return 1; 129 | 130 | if (!pCryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 131 | return 1; 132 | 133 | ok = pCryptGenRandom(hCryptProv, sizeof(uint32_t), data); 134 | pCryptReleaseContext(hCryptProv, 0); 135 | 136 | if (!ok) 137 | return 1; 138 | 139 | *seed = buf_to_uint32((char *)data); 140 | return 0; 141 | } 142 | #endif 143 | 144 | /* gettimeofday() and getpid() */ 145 | static int seed_from_timestamp_and_pid(uint32_t *seed) { 146 | #ifdef HAVE_GETTIMEOFDAY 147 | /* XOR of seconds and microseconds */ 148 | struct timeval tv; 149 | gettimeofday(&tv, NULL); 150 | *seed = (uint32_t)tv.tv_sec ^ (uint32_t)tv.tv_usec; 151 | #else 152 | /* Seconds only */ 153 | *seed = (uint32_t)time(NULL); 154 | #endif 155 | 156 | /* XOR with PID for more randomness */ 157 | #if defined(_WIN32) 158 | *seed ^= (uint32_t)GetCurrentProcessId(); 159 | #elif defined(HAVE_GETPID) 160 | *seed ^= (uint32_t)getpid(); 161 | #endif 162 | 163 | return 0; 164 | } 165 | 166 | static uint32_t generate_seed() { 167 | uint32_t seed = 0; 168 | int done = 0; 169 | 170 | #if !defined(_WIN32) && defined(USE_URANDOM) 171 | if (seed_from_urandom(&seed) == 0) 172 | done = 1; 173 | #endif 174 | 175 | #if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI) 176 | if (seed_from_windows_cryptoapi(&seed) == 0) 177 | done = 1; 178 | #endif 179 | 180 | if (!done) { 181 | /* Fall back to timestamp and PID if no better randomness is 182 | available */ 183 | seed_from_timestamp_and_pid(&seed); 184 | } 185 | 186 | /* Make sure the seed is never zero */ 187 | if (seed == 0) 188 | seed = 1; 189 | 190 | return seed; 191 | } 192 | 193 | 194 | volatile uint32_t hashtable_seed = 0; 195 | 196 | #if defined(HAVE_ATOMIC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32)) 197 | static volatile char seed_initialized = 0; 198 | 199 | void json_object_seed(size_t seed) { 200 | uint32_t new_seed = (uint32_t)seed; 201 | 202 | if (hashtable_seed == 0) { 203 | if (__atomic_test_and_set(&seed_initialized, __ATOMIC_RELAXED) == 0) { 204 | /* Do the seeding ourselves */ 205 | if (new_seed == 0) 206 | new_seed = generate_seed(); 207 | 208 | __atomic_store_n(&hashtable_seed, new_seed, __ATOMIC_RELEASE); 209 | } else { 210 | /* Wait for another thread to do the seeding */ 211 | do { 212 | #ifdef HAVE_SCHED_YIELD 213 | sched_yield(); 214 | #endif 215 | } while(__atomic_load_n(&hashtable_seed, __ATOMIC_ACQUIRE) == 0); 216 | } 217 | } 218 | } 219 | #elif defined(HAVE_SYNC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32)) 220 | void json_object_seed(size_t seed) { 221 | uint32_t new_seed = (uint32_t)seed; 222 | 223 | if (hashtable_seed == 0) { 224 | if (new_seed == 0) { 225 | /* Explicit synchronization fences are not supported by the 226 | __sync builtins, so every thread getting here has to 227 | generate the seed value. 228 | */ 229 | new_seed = generate_seed(); 230 | } 231 | 232 | do { 233 | if (__sync_bool_compare_and_swap(&hashtable_seed, 0, new_seed)) { 234 | /* We were the first to seed */ 235 | break; 236 | } else { 237 | /* Wait for another thread to do the seeding */ 238 | #ifdef HAVE_SCHED_YIELD 239 | sched_yield(); 240 | #endif 241 | } 242 | } while(hashtable_seed == 0); 243 | } 244 | } 245 | #elif defined(_WIN32) 246 | static long seed_initialized = 0; 247 | void json_object_seed(size_t seed) { 248 | uint32_t new_seed = (uint32_t)seed; 249 | 250 | if (hashtable_seed == 0) { 251 | if (InterlockedIncrement(&seed_initialized) == 1) { 252 | /* Do the seeding ourselves */ 253 | if (new_seed == 0) 254 | new_seed = generate_seed(); 255 | 256 | hashtable_seed = new_seed; 257 | } else { 258 | /* Wait for another thread to do the seeding */ 259 | do { 260 | SwitchToThread(); 261 | } while (hashtable_seed == 0); 262 | } 263 | } 264 | } 265 | #else 266 | /* Fall back to a thread-unsafe version */ 267 | void json_object_seed(size_t seed) { 268 | uint32_t new_seed = (uint32_t)seed; 269 | 270 | if (hashtable_seed == 0) { 271 | if (new_seed == 0) 272 | new_seed = generate_seed(); 273 | 274 | hashtable_seed = new_seed; 275 | } 276 | } 277 | #endif 278 | --------------------------------------------------------------------------------