diff --git a/Makefile b/Makefile index e01ed134..4f9872c4 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ GIS_DEP_TESTS = $(GIS_DEP_TESTS_DIR)/type $(GIS_DEP_TESTS_DIR)/auto_import $(GIS ifndef REGRESS # System tests, full default sequence -REGRESS = libsqlite extra/sqlite_fdw_post $(DATA_TYPE_TESTS) extra/join extra/limit extra/aggregates extra/prepare extra/select_having extra/select extra/insert extra/update extra/encodings sqlite_fdw aggregate selectfunc $(GIS_DEP_TESTS) +REGRESS = libsqlite extra/sqlite_fdw_post $(DATA_TYPE_TESTS) extra/join extra/limit extra/aggregates extra/prepare extra/select_having extra/select extra/insert extra/update extra/encodings sqlite_fdw aggregate selectfunc extra/returning $(GIS_DEP_TESTS) endif # Other encodings also are tested. Client encoding should be UTF-8. diff --git a/README.md b/README.md index 56daf87b..c6df7f3b 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,8 @@ Features - Support discard cached connections to foreign servers by using function `sqlite_fdw_disconnect()`, `sqlite_fdw_disconnect_all()`. - Support Bulk `INSERT` by using `batch_size` option - Support `INSERT`/`UPDATE` with generated column -- Support `ON CONFLICT DO NOTHING` +- Support `INSERT` ... `ON CONFLICT DO NOTHING` +- Support `WITH CHECK OPTION` views after a foreign table - Support mixed SQLite [data affinity](https://www.sqlite.org/datatype3.html) input and filtering (`SELECT`/`WHERE` usage) for such data types as - `timestamp`: `text` and `int`, - `uuid`: `text`(32..39) and `blob`(16), @@ -60,7 +61,7 @@ Features ### Pushing down - `WHERE` clauses are pushdowned -- Aggregate function are pushdowned +- Some aggregate functions are pushdowned - `ORDER BY` is pushdowned - Joins (left/right/inner/cross/semi) are pushdowned - `CASE` expressions are pushdowned. @@ -744,6 +745,13 @@ funct_name (type arg ...) } } ``` + +To debug, you need to build PostgreSQL in debug mode. Use the following options. +```bash +./configure --prefix= --enable-cassert --enable-debug CFLAGS="-ggdb -O0 -g3 -fno-omit-frame-pointer" +``` +Also please refer https://wiki.postgresql.org/wiki/Developer_FAQ#What_debugging_features_are_available.3F + Useful links ------------ diff --git a/connection.c b/connection.c index ba28120d..cd626160 100644 --- a/connection.c +++ b/connection.c @@ -184,6 +184,7 @@ sqlite_get_connection(ForeignServer *server, bool truncatable) } /* + * sqlite_open_db * Open remote sqlite database using specified database path * and flags of opened file descriptor mode. */ @@ -230,7 +231,7 @@ sqlite_make_new_connection(ConnCacheEntry *entry, ForeignServer *server) { const char *dbpath = NULL; ListCell *lc; - int flags = 0; + int flags = 0; Assert(entry->conn == NULL); @@ -389,9 +390,9 @@ sqlite_begin_remote_xact(ConnCacheEntry *entry) } } - /* - * Report an SQLite execution error. + * sqlitefdw_report_error + * Report an sqlite execution error */ void sqlitefdw_report_error(int elevel, sqlite3_stmt * stmt, sqlite3 * conn, @@ -401,7 +402,7 @@ sqlitefdw_report_error(int elevel, sqlite3_stmt * stmt, sqlite3 * conn, int erc = sqlite3_extended_errcode(conn); int sqlstate = ERRCODE_FDW_ERROR; - /* copy sql before callling another SQLite API */ + /* copy sql before calling another SQLite API */ if (message) message = pstrdup(message); @@ -420,7 +421,8 @@ sqlitefdw_report_error(int elevel, sqlite3_stmt * stmt, sqlite3 * conn, } /* - * sqlitefdw_xact_callback --- cleanup at main-transaction end. + * sqlitefdw_xact_callback + * cleanup at main-transaction end. */ static void sqlitefdw_xact_callback(XactEvent event, void *arg) @@ -1038,7 +1040,7 @@ sqlite_cache_stmt(ForeignServer *server, sqlite3_stmt * *stmt) } /* - * finalize all sqlite statement + * finalize all SQLite statement */ static void sqlite_finalize_list_stmt(List **list) diff --git a/deparse.c b/deparse.c index e7927965..7978f529 100644 --- a/deparse.c +++ b/deparse.c @@ -125,10 +125,25 @@ static void sqlite_print_remote_param(int paramindex, Oid paramtype, int32 param deparse_expr_cxt *context); static void sqlite_print_remote_placeholder(Oid paramtype, int32 paramtypmod, deparse_expr_cxt *context); -static void sqlite_deparse_relation(StringInfo buf, Relation rel); -static void sqlite_deparse_target_list(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, - Bitmapset *attrs_used, bool qualify_col, List **retrieved_attrs, bool is_concat, bool check_null); -static void sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col, bool dml_context); +static void sqlite_deparseRelation(StringInfo buf, Relation rel); +static void sqlite_deparseTargetList(StringInfo buf, + PlannerInfo *root, + Index rtindex, + Relation rel, + bool is_returning, + Bitmapset *attrs_used, + bool qualify_col, + List **retrieved_attrs, + bool is_concat, + bool check_null); +static void sqlite_deparseReturningList(StringInfo buf, + PlannerInfo *root, + Index rtindex, Relation rel, + bool trig_after_row, + List *withCheckOptionList, + List *returningList, + List **retrieved_attrs); +static void sqlite_deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col, bool dml_context); static void sqlite_deparse_select(List *tlist, bool is_subquery, List **retrieved_attrs, deparse_expr_cxt *context); static void sqlite_deparse_subquery_target_list(deparse_expr_cxt *context); static void sqlite_deparse_case_expr(CaseExpr *node, deparse_expr_cxt *context); @@ -165,8 +180,10 @@ static void sqlite_append_function_name(Oid funcid, deparse_expr_cxt *context); const char *sqlite_get_jointype_name(JoinType jointype); static Node *sqlite_deparse_sort_group_clause(Index ref, List *tlist, bool force_colno, deparse_expr_cxt *context); -static void sqlite_deparse_explicit_target_list(List *tlist, List **retrieved_attrs, - deparse_expr_cxt *context); +static void sqlite_deparseExplicitTargetList(List *tlist, + bool is_returning, + List **retrieved_attrs, + deparse_expr_cxt *context); /* * Helper functions @@ -179,6 +196,7 @@ static char *sqlite_quote_identifier(const char *s, char q); static bool sqlite_contain_immutable_functions_walker(Node *node, void *context); static bool sqlite_deparsable_data_type(Param *p); static int preferred_sqlite_affinity (Oid relid, int varattno); +static void sqlite_dmlAppendCondition(StringInfo buf, PlannerInfo *root, Index rtindex, List *conditionAttr); /* * Append remote name of specified foreign table to buf. @@ -186,7 +204,7 @@ static int preferred_sqlite_affinity (Oid relid, int varattno); * Similarly, schema_name FDW option overrides schema name. */ static void -sqlite_deparse_relation(StringInfo buf, Relation rel) +sqlite_deparseRelation(StringInfo buf, Relation rel) { ForeignTable *table; const char *relname = NULL; @@ -1405,7 +1423,7 @@ sqlite_deparse_select(List *tlist, bool is_subquery, List **retrieved_attrs, dep * For a join or upper relation the input tlist gives the list of * columns required to be fetched from the foreign server. */ - sqlite_deparse_explicit_target_list(tlist, retrieved_attrs, context); + sqlite_deparseExplicitTargetList(tlist, false, retrieved_attrs, context); } else { @@ -1421,7 +1439,7 @@ sqlite_deparse_select(List *tlist, bool is_subquery, List **retrieved_attrs, dep */ Relation rel = table_open(rte->relid, NoLock); - sqlite_deparse_target_list(buf, root, foreignrel->relid, rel, fpinfo->attrs_used, false, retrieved_attrs, false, false); + sqlite_deparseTargetList(buf, root, foreignrel->relid, rel, false, fpinfo->attrs_used, false, retrieved_attrs, false, false); table_close(rel, NoLock); } @@ -1550,8 +1568,10 @@ sqlite_get_jointype_name(JoinType jointype) * from 1. It has same number of entries as tlist. */ static void -sqlite_deparse_explicit_target_list(List *tlist, List **retrieved_attrs, - deparse_expr_cxt *context) +sqlite_deparseExplicitTargetList(List *tlist, + bool is_returning, + List **retrieved_attrs, + deparse_expr_cxt *context) { ListCell *lc; StringInfo buf = context->buf; @@ -1565,13 +1585,15 @@ sqlite_deparse_explicit_target_list(List *tlist, List **retrieved_attrs, if (i > 0) appendStringInfoString(buf, ", "); + else if (is_returning) + appendStringInfoString(buf, " RETURNING "); sqlite_deparse_expr((Expr *) tle->expr, context); *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1); i++; } - if (i == 0) + if (i == 0 && !is_returning) appendStringInfoString(buf, "NULL"); } @@ -1874,7 +1896,7 @@ sqlite_deparse_from_expr_for_rel(StringInfo buf, PlannerInfo *root, RelOptInfo * */ Relation rel = table_open(rte->relid, NoLock); - sqlite_deparse_relation(buf, rel); + sqlite_deparseRelation(buf, rel); /* * Add a unique alias to avoid any conflict in relation names due to @@ -1943,6 +1965,60 @@ sqlite_deparse_range_tbl_ref(StringInfo buf, PlannerInfo *root, RelOptInfo *fore params_list); } +/* + * Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE. + */ +static void +sqlite_deparseReturningList(StringInfo buf, PlannerInfo *root, + Index rtindex, Relation rel, + bool trig_after_row, + List *withCheckOptionList, + List *returningList, + List **retrieved_attrs) +{ + Bitmapset *attrs_used = NULL; + + elog(DEBUG3, "sqlite_fdw : %s", __func__); + if (trig_after_row) + { + /* whole-row reference acquires all non-system columns */ + attrs_used = + bms_make_singleton(0 - FirstLowInvalidHeapAttributeNumber); + } + + if (withCheckOptionList != NIL) + { + /* + * We need the attrs, non-system and system, mentioned in the local + * query's WITH CHECK OPTION list. + * + * Note: we do this to ensure that WCO constraints will be evaluated + * on the data actually inserted/updated on the remote side, which + * might differ from the data supplied by the core code, for example + * as a result of remote triggers. + */ + pull_varattnos((Node *) withCheckOptionList, rtindex, + &attrs_used); + } + + if (returningList != NIL) + { + /* + * We need the attrs, non-system and system, mentioned in the local + * query's RETURNING list. + */ + pull_varattnos((Node *) returningList, rtindex, + &attrs_used); + } + if (attrs_used != NULL) + { + sqlite_deparseTargetList(buf, root, rtindex, rel, true, attrs_used, false, + retrieved_attrs, false, false); + } + else + *retrieved_attrs = NIL; +} + /* * deparse remote INSERT statement * @@ -1951,10 +2027,11 @@ sqlite_deparse_range_tbl_ref(StringInfo buf, PlannerInfo *root, RelOptInfo *fore * to *retrieved_attrs. */ void -sqlite_deparse_insert(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *targetAttrs, bool doNothing, - int *values_end_len) +sqlite_deparseInsertSql(StringInfo buf, PlannerInfo *root, + Index rtindex, Relation rel, + List *targetAttrs, bool doNothing, + List *withCheckOptionList, List *returningList, + List **retrieved_attrs, int *values_end_len) { #if PG_VERSION_NUM >= 140000 TupleDesc tupdesc = RelationGetDescr(rel); @@ -1964,8 +2041,12 @@ sqlite_deparse_insert(StringInfo buf, PlannerInfo *root, bool first; ListCell *lc; - appendStringInfo(buf, "INSERT %sINTO ", doNothing ? "OR IGNORE " : ""); - sqlite_deparse_relation(buf, rel); + elog(DEBUG3, "sqlite_fdw : %s", __func__); + appendStringInfo(buf, "INSERT "); + if (doNothing) + appendStringInfo(buf, "OR IGNORE "); + appendStringInfo(buf, "INTO "); + sqlite_deparseRelation(buf, rel); #if PG_VERSION_NUM >= 140000 @@ -2012,7 +2093,7 @@ sqlite_deparse_insert(StringInfo buf, PlannerInfo *root, appendStringInfoString(buf, ", "); first = false; - sqlite_deparse_column_ref(buf, rtindex, attnum, root, false, true); + sqlite_deparseColumnRef(buf, rtindex, attnum, root, false, true); #if PG_VERSION_NUM >= 140000 } #endif @@ -2045,6 +2126,16 @@ sqlite_deparse_insert(StringInfo buf, PlannerInfo *root, } else appendStringInfoString(buf, " DEFAULT VALUES"); + + /* + * postgres_fdw if (doNothing) + * see INSERT OR IGNORE at begin + */ + + sqlite_deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_insert_after_row, + withCheckOptionList, returningList, retrieved_attrs); + *values_end_len = buf->len; } @@ -2117,21 +2208,23 @@ sqlite_deparse_analyze(StringInfo sql, char *dbname, char *relname) * This is used for both SELECT and RETURNING targetlists. */ static void -sqlite_deparse_target_list(StringInfo buf, - PlannerInfo *root, - Index rtindex, - Relation rel, - Bitmapset *attrs_used, - bool qualify_col, - List **retrieved_attrs, - bool is_concat, - bool check_null) +sqlite_deparseTargetList(StringInfo buf, + PlannerInfo *root, + Index rtindex, + Relation rel, + bool is_returning, + Bitmapset *attrs_used, + bool qualify_col, + List **retrieved_attrs, + bool is_concat, + bool check_null) { TupleDesc tupdesc = RelationGetDescr(rel); bool have_wholerow; bool first; int i; + elog(DEBUG3, "sqlite_fdw : %s", __func__); /* If there's a whole-row reference, we'll need all the columns. */ have_wholerow = bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, attrs_used); @@ -2159,14 +2252,15 @@ sqlite_deparse_target_list(StringInfo buf, else appendStringInfoString(buf, ", "); } + else if (is_returning) + appendStringInfoString(buf, " RETURNING "); else if (is_concat) appendStringInfoString(buf, "COALESCE("); else if (check_null) appendStringInfoString(buf, "( "); - first = false; - sqlite_deparse_column_ref(buf, rtindex, i, root, qualify_col, false); + sqlite_deparseColumnRef(buf, rtindex, i, root, qualify_col, false); if (check_null) appendStringInfoString(buf, " IS NOT NULL) "); @@ -2239,7 +2333,7 @@ sqlite_deparse_truncate(StringInfo buf, rel = lfirst(cell); - sqlite_deparse_relation(buf, rel); + sqlite_deparseRelation(buf, rel); appendStringInfoChar(buf, ';'); } } @@ -2250,7 +2344,7 @@ sqlite_deparse_truncate(StringInfo buf, * If it has a column_name FDW option, use that instead of attribute name. */ static void -sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col, bool dml_context) +sqlite_deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col, bool dml_context) { RangeTblEntry *rte; @@ -2265,6 +2359,7 @@ sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo * /* Required only to be passed down to deparseTargetList(). */ List *retrieved_attrs; + elog(DEBUG4, "sqlite_fdw : %s , whole row reference", __func__); /* * The lock on the relation will be held by upper callers, so it's * fine to open it with no lock here. @@ -2289,12 +2384,12 @@ sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo * * would be true. */ appendStringInfoString(buf, "CASE WHEN "); - sqlite_deparse_target_list(buf, root, varno, rel, attrs_used, qualify_col, + sqlite_deparseTargetList(buf, root, varno, rel, false, attrs_used, qualify_col, &retrieved_attrs, false, true); appendStringInfoString(buf, "THEN "); appendStringInfoString(buf, "(\"(\" || "); - sqlite_deparse_target_list(buf, root, varno, rel, attrs_used, qualify_col, + sqlite_deparseTargetList(buf, root, varno, rel, false, attrs_used, qualify_col, &retrieved_attrs, true, false); appendStringInfoString(buf, "|| \")\")"); appendStringInfoString(buf, " END"); @@ -2312,6 +2407,7 @@ sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo * char *coltype = NULL; int colaff = SQLITE_NULL; + elog(DEBUG4, "sqlite_fdw : %s , col reference", __func__); /* varno must not be any of OUTER_VAR, INNER_VAR and INDEX_VAR. */ Assert(!IS_SPECIAL_VARNO(varno)); @@ -2634,6 +2730,58 @@ sqlite_deparse_expr(Expr *node, deparse_expr_cxt *context) } } +/* + * Preferred SQLite affinity from "column_type" foreign column option + * SQLITE_NULL if no value or no normal value + */ +static int +preferred_sqlite_affinity (Oid relid, int varattno) +{ + char *coltype = NULL; + List *options; + ListCell *lc; + + elog(DEBUG4, "sqlite_fdw : %s ", __func__); + if (varattno == 0) + return SQLITE_NULL; + + options = GetForeignColumnOptions(relid, varattno); + foreach(lc, options) + { + DefElem *def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "column_type") == 0) + { + coltype = defGetString(def); + elog(DEBUG4, "column type = %s", coltype); + break; + } + } + return sqlite_affinity_code(coltype); +} + +/* + * sqlite_dmlAppendCondition + * Add special conditions for UPDATE and DELETE + * + */ +static void +sqlite_dmlAppendCondition(StringInfo buf, PlannerInfo *root, Index rtindex, List *conditionAttr) +{ + int i = 0; + ListCell *lc; + + foreach(lc, conditionAttr) + { + int attnum = lfirst_int(lc); + + appendStringInfo(buf, i == 0 ? " WHERE " : " AND "); + sqlite_deparseColumnRef(buf, rtindex, attnum, root, false, true); + appendStringInfo(buf, "=?"); + i++; + } +} + /* * deparse remote UPDATE statement * @@ -2642,9 +2790,12 @@ sqlite_deparse_expr(Expr *node, deparse_expr_cxt *context) * to *retrieved_attrs. */ void -sqlite_deparse_update(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *targetAttrs, List *attnums) +sqlite_deparseUpdateSql(StringInfo buf, PlannerInfo *root, + Index rtindex, Relation rel, + List *targetAttrs, + List *withCheckOptionList, List *returningList, + List **retrieved_attrs, + List *conditionAttr) { #if PG_VERSION_NUM >= 140000 TupleDesc tupdesc = RelationGetDescr(rel); @@ -2652,10 +2803,9 @@ sqlite_deparse_update(StringInfo buf, PlannerInfo *root, AttrNumber pindex; bool first; ListCell *lc; - int i; appendStringInfoString(buf, "UPDATE "); - sqlite_deparse_relation(buf, rel); + sqlite_deparseRelation(buf, rel); appendStringInfoString(buf, " SET "); pindex = 2; @@ -2672,53 +2822,18 @@ sqlite_deparse_update(StringInfo buf, PlannerInfo *root, if (!first) appendStringInfoString(buf, ", "); first = false; - sqlite_deparse_column_ref(buf, rtindex, attnum, root, false, true); + sqlite_deparseColumnRef(buf, rtindex, attnum, root, false, true); appendStringInfo(buf, " = ?"); pindex++; #if PG_VERSION_NUM >= 140000 } #endif } - i = 0; - foreach(lc, attnums) - { - int attnum = lfirst_int(lc); - - appendStringInfo(buf, i == 0 ? " WHERE " : " AND "); - sqlite_deparse_column_ref(buf, rtindex, attnum, root, false, true); - appendStringInfo(buf, "=?"); - i++; - } -} - -/* - * Preferred SQLite affinity from "column_type" foreign column option - * SQLITE_NULL if no value or no normal value - */ -int -preferred_sqlite_affinity (Oid relid, int varattno) -{ - char *coltype = NULL; - List *options; - ListCell *lc; - - elog(DEBUG4, "sqlite_fdw : %s ", __func__); - if (varattno == 0) - return SQLITE_NULL; - - options = GetForeignColumnOptions(relid, varattno); - foreach(lc, options) - { - DefElem *def = (DefElem *) lfirst(lc); - if (strcmp(def->defname, "column_type") == 0) - { - coltype = defGetString(def); - elog(DEBUG4, "column type = %s", coltype); - break; - } - } - return sqlite_affinity_code(coltype); + sqlite_dmlAppendCondition(buf, root, rtindex, conditionAttr); + sqlite_deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_insert_after_row, + withCheckOptionList, returningList, retrieved_attrs); } /* @@ -2735,13 +2850,14 @@ preferred_sqlite_affinity (Oid relid, int varattno) * output list of integers of columns being retrieved by RETURNING (if any) */ void -sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, +sqlite_deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, RelOptInfo *foreignrel, List *targetlist, List *targetAttrs, List *remote_conds, List **params_list, + List *returningList, List **retrieved_attrs) { deparse_expr_cxt context; @@ -2762,7 +2878,7 @@ sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, context.params_list = params_list; appendStringInfoString(buf, "UPDATE "); - sqlite_deparse_relation(buf, rel); + sqlite_deparseRelation(buf, rel); if (IS_JOIN_REL(foreignrel)) appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex); appendStringInfoString(buf, " SET "); @@ -2797,7 +2913,7 @@ sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, appendStringInfoString(buf, ", "); first = false; - sqlite_deparse_column_ref(buf, rtindex, attnum, root, false, true); + sqlite_deparseColumnRef(buf, rtindex, attnum, root, false, true); /* Get RangeTblEntry from array in PlannerInfo. */ rte = planner_rt_fetch(rtindex, root); @@ -2864,8 +2980,15 @@ sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, sqlite_append_conditions(remote_conds, &context); } #endif + if (foreignrel->reloptkind == RELOPT_JOINREL) + sqlite_deparseExplicitTargetList(returningList, true, retrieved_attrs, + &context); + else + sqlite_deparseReturningList(buf, root, rtindex, rel, false, + NIL, returningList, retrieved_attrs); } + /* * deparse remote DELETE statement * @@ -2874,24 +2997,19 @@ sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, * to *retrieved_attrs. */ void -sqlite_deparse_delete(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *attname) +sqlite_deparseDeleteSql(StringInfo buf, PlannerInfo *root, + Index rtindex, Relation rel, + List *returningList, + List **retrieved_attrs, + List *conditionAttr) { - int i = 0; - ListCell *lc; - appendStringInfoString(buf, "DELETE FROM "); - sqlite_deparse_relation(buf, rel); - foreach(lc, attname) - { - int attnum = lfirst_int(lc); + sqlite_deparseRelation(buf, rel); - appendStringInfo(buf, i == 0 ? " WHERE " : " AND "); - sqlite_deparse_column_ref(buf, rtindex, attnum, root, false, true); - appendStringInfo(buf, "=?"); - i++; - } + sqlite_dmlAppendCondition(buf, root, rtindex, conditionAttr); + sqlite_deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_delete_after_row, + NIL, returningList, retrieved_attrs); } /* @@ -2907,11 +3025,12 @@ sqlite_deparse_delete(StringInfo buf, PlannerInfo *root, * retrieved by RETURNING (if any) */ void -sqlite_deparse_direct_delete_sql(StringInfo buf, PlannerInfo *root, +sqlite_deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, RelOptInfo *foreignrel, List *remote_conds, List **params_list, + List *returningList, List **retrieved_attrs) { deparse_expr_cxt context; @@ -2928,7 +3047,7 @@ sqlite_deparse_direct_delete_sql(StringInfo buf, PlannerInfo *root, context.params_list = params_list; appendStringInfoString(buf, "DELETE FROM "); - sqlite_deparse_relation(buf, rel); + sqlite_deparseRelation(buf, rel); if (IS_JOIN_REL(foreignrel)) appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex); @@ -2957,6 +3076,13 @@ sqlite_deparse_direct_delete_sql(StringInfo buf, PlannerInfo *root, sqlite_append_conditions(remote_conds, &context); } #endif + if (foreignrel->reloptkind == RELOPT_JOINREL) + sqlite_deparseExplicitTargetList(returningList, true, retrieved_attrs, + &context); + else + sqlite_deparseReturningList(buf, root, + rtindex, rel, false, + NIL, returningList, retrieved_attrs); } /* @@ -2994,7 +3120,7 @@ sqlite_deparse_var(Var *node, deparse_expr_cxt *context) if (bms_is_member(node->varno, relids) && node->varlevelsup == 0) { /* Var belongs to foreign table */ - sqlite_deparse_column_ref(buf, node->varno, node->varattno, context->root, qualify_col, false); + sqlite_deparseColumnRef(buf, node->varno, node->varattno, context->root, qualify_col, false); } else { diff --git a/expected/13.15/extra/returning.out b/expected/13.15/extra/returning.out new file mode 100644 index 00000000..b4fe65a1 --- /dev/null +++ b/expected/13.15/extra/returning.out @@ -0,0 +1,581 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; +--Testcase 05: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 08: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 13: +SELECT * FROM "type_BYTE"; + col +----- +(0 rows) + +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 16: +SELECT * FROM "type_SINT"; + col +----- +(0 rows) + +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 18: +SELECT * FROM "type_BINT"; + col +----- +(0 rows) + +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 20: +SELECT * FROM "type_INTEGER"; + col +----- +(0 rows) + +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 22: +SELECT * FROM "type_FLOAT"; + col +----- +(0 rows) + +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 24: +SELECT * FROM "type_DOUBLE"; + col +----- +(0 rows) + +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +ERROR: RETURNING clause is not supported +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; + col | b +-----+--- +(0 rows) + +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 28: +SELECT * FROM "type_BLOB"; + col +----- +(0 rows) + +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 35: +SELECT * FROM typetest; + i | v | c | t | d | ti +---+---+---+---+---+---- +(0 rows) + +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 49: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 56: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 57: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 60: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 65: +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 66: +DELETE FROM type_JSON RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 111: +SELECT * FROM ret_base; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 113: +SELECT * FROM ret_j1t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 115: +SELECT * FROM ret_j2t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +ERROR: RETURNING clause is not supported +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; +ERROR: RETURNING clause is not supported +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (10, 50, uuuuu). +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (25, 40, uuuuu). +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; + QUERY PLAN +------------------------------------- + Insert on public."type_STRING" + Conflict Resolution: NOTHING + -> Result + Output: 'string_ocdn'::text +(4 rows) + +--Testcase 142: +DELETE FROM "type_STRING"; +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; +NOTICE: drop cascades to 62 other objects +DETAIL: drop cascades to server sqlite_svr +drop cascades to foreign table department +drop cascades to foreign table employee +drop cascades to foreign table empdata +drop cascades to foreign table numbers +drop cascades to foreign table t +drop cascades to foreign table multiprimary +drop cascades to foreign table columntest +drop cascades to foreign table noprimary +drop cascades to foreign table limittest +drop cascades to foreign table grem1_1 +drop cascades to foreign table grem1_2 +drop cascades to foreign table case_exp +drop cascades to foreign table "type_STRING" +drop cascades to foreign table "type_BOOLEANpk" +drop cascades to foreign table "type_BOOLEAN" +drop cascades to foreign table "type_BYTE" +drop cascades to foreign table "type_SINT" +drop cascades to foreign table "type_BINT" +drop cascades to foreign table "type_INTEGER" +drop cascades to foreign table "type_FLOAT" +drop cascades to foreign table "type_DOUBLE" +drop cascades to foreign table "type_TIMESTAMP" +drop cascades to foreign table "type_BLOB" +drop cascades to foreign table "type_DATE" +drop cascades to foreign table "type_TIME" +drop cascades to foreign table "type_BIT" +drop cascades to foreign table "type_VARBIT" +drop cascades to foreign table "type_UUIDpk" +drop cascades to foreign table "type_UUID" +drop cascades to foreign table "type_MACADDRpk" +drop cascades to foreign table "type_MACADDR" +drop cascades to foreign table "type_MACADDR8pk" +drop cascades to foreign table "type_MACADDR8" +drop cascades to foreign table "type_JSON" +drop cascades to foreign table "type_JSONB" +drop cascades to foreign table "BitT" +drop cascades to foreign table notype +drop cascades to foreign table typetest +drop cascades to foreign table "type_TEXT" +drop cascades to foreign table alltypetest +drop cascades to foreign table json_osm_test +drop cascades to foreign table shorty +drop cascades to foreign table "A a" +drop cascades to foreign table fts_table +drop cascades to foreign table fts_table_data +drop cascades to foreign table fts_table_idx +drop cascades to foreign table fts_table_content +drop cascades to foreign table fts_table_docsize +drop cascades to foreign table fts_table_config +drop cascades to foreign table "RO_RW_test" +drop cascades to foreign table "Unicode data" +drop cascades to foreign table "type_BOOLEAN_oper" +drop cascades to foreign table ret_base +drop cascades to foreign table ret_j1t +drop cascades to foreign table ret_j2t +drop cascades to foreign table type_json +drop cascades to server sqlite2 +drop cascades to server sqlite_svr_ins +drop cascades to foreign table inserttest01 +drop cascades to view inserttest01_view_wco +drop cascades to view inserttest01_view diff --git a/expected/13.15/with_gis_support/auto_import.out b/expected/13.15/with_gis_support/auto_import.out index 95055559..75b0ea12 100644 --- a/expected/13.15/with_gis_support/auto_import.out +++ b/expected/13.15/with_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/13.15/without_gis_support/auto_import.out b/expected/13.15/without_gis_support/auto_import.out index 4c399770..3e7e4546 100644 --- a/expected/13.15/without_gis_support/auto_import.out +++ b/expected/13.15/without_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/14.12/extra/returning.out b/expected/14.12/extra/returning.out new file mode 100644 index 00000000..2fe8a795 --- /dev/null +++ b/expected/14.12/extra/returning.out @@ -0,0 +1,582 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; +--Testcase 05: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 08: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 13: +SELECT * FROM "type_BYTE"; + col +----- +(0 rows) + +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 16: +SELECT * FROM "type_SINT"; + col +----- +(0 rows) + +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 18: +SELECT * FROM "type_BINT"; + col +----- +(0 rows) + +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 20: +SELECT * FROM "type_INTEGER"; + col +----- +(0 rows) + +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 22: +SELECT * FROM "type_FLOAT"; + col +----- +(0 rows) + +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 24: +SELECT * FROM "type_DOUBLE"; + col +----- +(0 rows) + +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +ERROR: RETURNING clause is not supported +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; + col | b +-----+--- +(0 rows) + +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 28: +SELECT * FROM "type_BLOB"; + col +----- +(0 rows) + +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 35: +SELECT * FROM typetest; + i | v | c | t | d | ti +---+---+---+---+---+---- +(0 rows) + +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 49: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 56: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 57: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 60: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 65: +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 66: +DELETE FROM type_JSON RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 111: +SELECT * FROM ret_base; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 113: +SELECT * FROM ret_j1t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 115: +SELECT * FROM ret_j2t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +ERROR: RETURNING clause is not supported +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; +ERROR: RETURNING clause is not supported +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (10, 50, uuuuu). +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (25, 40, uuuuu). +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; + QUERY PLAN +------------------------------------- + Insert on public."type_STRING" + Batch Size: 1 + Conflict Resolution: NOTHING + -> Result + Output: 'string_ocdn'::text +(5 rows) + +--Testcase 142: +DELETE FROM "type_STRING"; +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; +NOTICE: drop cascades to 62 other objects +DETAIL: drop cascades to server sqlite_svr +drop cascades to foreign table department +drop cascades to foreign table employee +drop cascades to foreign table empdata +drop cascades to foreign table numbers +drop cascades to foreign table t +drop cascades to foreign table multiprimary +drop cascades to foreign table columntest +drop cascades to foreign table noprimary +drop cascades to foreign table limittest +drop cascades to foreign table grem1_1 +drop cascades to foreign table grem1_2 +drop cascades to foreign table case_exp +drop cascades to foreign table "type_STRING" +drop cascades to foreign table "type_BOOLEANpk" +drop cascades to foreign table "type_BOOLEAN" +drop cascades to foreign table "type_BYTE" +drop cascades to foreign table "type_SINT" +drop cascades to foreign table "type_BINT" +drop cascades to foreign table "type_INTEGER" +drop cascades to foreign table "type_FLOAT" +drop cascades to foreign table "type_DOUBLE" +drop cascades to foreign table "type_TIMESTAMP" +drop cascades to foreign table "type_BLOB" +drop cascades to foreign table "type_DATE" +drop cascades to foreign table "type_TIME" +drop cascades to foreign table "type_BIT" +drop cascades to foreign table "type_VARBIT" +drop cascades to foreign table "type_UUIDpk" +drop cascades to foreign table "type_UUID" +drop cascades to foreign table "type_MACADDRpk" +drop cascades to foreign table "type_MACADDR" +drop cascades to foreign table "type_MACADDR8pk" +drop cascades to foreign table "type_MACADDR8" +drop cascades to foreign table "type_JSON" +drop cascades to foreign table "type_JSONB" +drop cascades to foreign table "BitT" +drop cascades to foreign table notype +drop cascades to foreign table typetest +drop cascades to foreign table "type_TEXT" +drop cascades to foreign table alltypetest +drop cascades to foreign table json_osm_test +drop cascades to foreign table shorty +drop cascades to foreign table "A a" +drop cascades to foreign table fts_table +drop cascades to foreign table fts_table_data +drop cascades to foreign table fts_table_idx +drop cascades to foreign table fts_table_content +drop cascades to foreign table fts_table_docsize +drop cascades to foreign table fts_table_config +drop cascades to foreign table "RO_RW_test" +drop cascades to foreign table "Unicode data" +drop cascades to foreign table "type_BOOLEAN_oper" +drop cascades to foreign table ret_base +drop cascades to foreign table ret_j1t +drop cascades to foreign table ret_j2t +drop cascades to foreign table type_json +drop cascades to server sqlite2 +drop cascades to server sqlite_svr_ins +drop cascades to foreign table inserttest01 +drop cascades to view inserttest01_view_wco +drop cascades to view inserttest01_view diff --git a/expected/14.12/with_gis_support/auto_import.out b/expected/14.12/with_gis_support/auto_import.out index 95055559..75b0ea12 100644 --- a/expected/14.12/with_gis_support/auto_import.out +++ b/expected/14.12/with_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/14.12/without_gis_support/auto_import.out b/expected/14.12/without_gis_support/auto_import.out index 4c399770..3e7e4546 100644 --- a/expected/14.12/without_gis_support/auto_import.out +++ b/expected/14.12/without_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/15.7/extra/returning.out b/expected/15.7/extra/returning.out new file mode 100644 index 00000000..2fe8a795 --- /dev/null +++ b/expected/15.7/extra/returning.out @@ -0,0 +1,582 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; +--Testcase 05: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 08: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 13: +SELECT * FROM "type_BYTE"; + col +----- +(0 rows) + +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 16: +SELECT * FROM "type_SINT"; + col +----- +(0 rows) + +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 18: +SELECT * FROM "type_BINT"; + col +----- +(0 rows) + +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 20: +SELECT * FROM "type_INTEGER"; + col +----- +(0 rows) + +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 22: +SELECT * FROM "type_FLOAT"; + col +----- +(0 rows) + +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 24: +SELECT * FROM "type_DOUBLE"; + col +----- +(0 rows) + +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +ERROR: RETURNING clause is not supported +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; + col | b +-----+--- +(0 rows) + +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 28: +SELECT * FROM "type_BLOB"; + col +----- +(0 rows) + +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 35: +SELECT * FROM typetest; + i | v | c | t | d | ti +---+---+---+---+---+---- +(0 rows) + +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 49: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 56: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 57: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 60: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 65: +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 66: +DELETE FROM type_JSON RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 111: +SELECT * FROM ret_base; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 113: +SELECT * FROM ret_j1t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 115: +SELECT * FROM ret_j2t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +ERROR: RETURNING clause is not supported +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; +ERROR: RETURNING clause is not supported +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (10, 50, uuuuu). +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (25, 40, uuuuu). +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; + QUERY PLAN +------------------------------------- + Insert on public."type_STRING" + Batch Size: 1 + Conflict Resolution: NOTHING + -> Result + Output: 'string_ocdn'::text +(5 rows) + +--Testcase 142: +DELETE FROM "type_STRING"; +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; +NOTICE: drop cascades to 62 other objects +DETAIL: drop cascades to server sqlite_svr +drop cascades to foreign table department +drop cascades to foreign table employee +drop cascades to foreign table empdata +drop cascades to foreign table numbers +drop cascades to foreign table t +drop cascades to foreign table multiprimary +drop cascades to foreign table columntest +drop cascades to foreign table noprimary +drop cascades to foreign table limittest +drop cascades to foreign table grem1_1 +drop cascades to foreign table grem1_2 +drop cascades to foreign table case_exp +drop cascades to foreign table "type_STRING" +drop cascades to foreign table "type_BOOLEANpk" +drop cascades to foreign table "type_BOOLEAN" +drop cascades to foreign table "type_BYTE" +drop cascades to foreign table "type_SINT" +drop cascades to foreign table "type_BINT" +drop cascades to foreign table "type_INTEGER" +drop cascades to foreign table "type_FLOAT" +drop cascades to foreign table "type_DOUBLE" +drop cascades to foreign table "type_TIMESTAMP" +drop cascades to foreign table "type_BLOB" +drop cascades to foreign table "type_DATE" +drop cascades to foreign table "type_TIME" +drop cascades to foreign table "type_BIT" +drop cascades to foreign table "type_VARBIT" +drop cascades to foreign table "type_UUIDpk" +drop cascades to foreign table "type_UUID" +drop cascades to foreign table "type_MACADDRpk" +drop cascades to foreign table "type_MACADDR" +drop cascades to foreign table "type_MACADDR8pk" +drop cascades to foreign table "type_MACADDR8" +drop cascades to foreign table "type_JSON" +drop cascades to foreign table "type_JSONB" +drop cascades to foreign table "BitT" +drop cascades to foreign table notype +drop cascades to foreign table typetest +drop cascades to foreign table "type_TEXT" +drop cascades to foreign table alltypetest +drop cascades to foreign table json_osm_test +drop cascades to foreign table shorty +drop cascades to foreign table "A a" +drop cascades to foreign table fts_table +drop cascades to foreign table fts_table_data +drop cascades to foreign table fts_table_idx +drop cascades to foreign table fts_table_content +drop cascades to foreign table fts_table_docsize +drop cascades to foreign table fts_table_config +drop cascades to foreign table "RO_RW_test" +drop cascades to foreign table "Unicode data" +drop cascades to foreign table "type_BOOLEAN_oper" +drop cascades to foreign table ret_base +drop cascades to foreign table ret_j1t +drop cascades to foreign table ret_j2t +drop cascades to foreign table type_json +drop cascades to server sqlite2 +drop cascades to server sqlite_svr_ins +drop cascades to foreign table inserttest01 +drop cascades to view inserttest01_view_wco +drop cascades to view inserttest01_view diff --git a/expected/15.7/with_gis_support/auto_import.out b/expected/15.7/with_gis_support/auto_import.out index 95055559..75b0ea12 100644 --- a/expected/15.7/with_gis_support/auto_import.out +++ b/expected/15.7/with_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/15.7/without_gis_support/auto_import.out b/expected/15.7/without_gis_support/auto_import.out index 4c399770..3e7e4546 100644 --- a/expected/15.7/without_gis_support/auto_import.out +++ b/expected/15.7/without_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/16.3/extra/returning.out b/expected/16.3/extra/returning.out new file mode 100644 index 00000000..2fe8a795 --- /dev/null +++ b/expected/16.3/extra/returning.out @@ -0,0 +1,582 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; +--Testcase 05: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 08: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 13: +SELECT * FROM "type_BYTE"; + col +----- +(0 rows) + +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 16: +SELECT * FROM "type_SINT"; + col +----- +(0 rows) + +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 18: +SELECT * FROM "type_BINT"; + col +----- +(0 rows) + +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 20: +SELECT * FROM "type_INTEGER"; + col +----- +(0 rows) + +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 22: +SELECT * FROM "type_FLOAT"; + col +----- +(0 rows) + +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 24: +SELECT * FROM "type_DOUBLE"; + col +----- +(0 rows) + +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +ERROR: RETURNING clause is not supported +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; + col | b +-----+--- +(0 rows) + +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 28: +SELECT * FROM "type_BLOB"; + col +----- +(0 rows) + +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 35: +SELECT * FROM typetest; + i | v | c | t | d | ti +---+---+---+---+---+---- +(0 rows) + +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 49: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 56: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 57: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 60: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 65: +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 66: +DELETE FROM type_JSON RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 111: +SELECT * FROM ret_base; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 113: +SELECT * FROM ret_j1t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 115: +SELECT * FROM ret_j2t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +ERROR: RETURNING clause is not supported +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; +ERROR: RETURNING clause is not supported +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (10, 50, uuuuu). +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (25, 40, uuuuu). +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; + QUERY PLAN +------------------------------------- + Insert on public."type_STRING" + Batch Size: 1 + Conflict Resolution: NOTHING + -> Result + Output: 'string_ocdn'::text +(5 rows) + +--Testcase 142: +DELETE FROM "type_STRING"; +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; +NOTICE: drop cascades to 62 other objects +DETAIL: drop cascades to server sqlite_svr +drop cascades to foreign table department +drop cascades to foreign table employee +drop cascades to foreign table empdata +drop cascades to foreign table numbers +drop cascades to foreign table t +drop cascades to foreign table multiprimary +drop cascades to foreign table columntest +drop cascades to foreign table noprimary +drop cascades to foreign table limittest +drop cascades to foreign table grem1_1 +drop cascades to foreign table grem1_2 +drop cascades to foreign table case_exp +drop cascades to foreign table "type_STRING" +drop cascades to foreign table "type_BOOLEANpk" +drop cascades to foreign table "type_BOOLEAN" +drop cascades to foreign table "type_BYTE" +drop cascades to foreign table "type_SINT" +drop cascades to foreign table "type_BINT" +drop cascades to foreign table "type_INTEGER" +drop cascades to foreign table "type_FLOAT" +drop cascades to foreign table "type_DOUBLE" +drop cascades to foreign table "type_TIMESTAMP" +drop cascades to foreign table "type_BLOB" +drop cascades to foreign table "type_DATE" +drop cascades to foreign table "type_TIME" +drop cascades to foreign table "type_BIT" +drop cascades to foreign table "type_VARBIT" +drop cascades to foreign table "type_UUIDpk" +drop cascades to foreign table "type_UUID" +drop cascades to foreign table "type_MACADDRpk" +drop cascades to foreign table "type_MACADDR" +drop cascades to foreign table "type_MACADDR8pk" +drop cascades to foreign table "type_MACADDR8" +drop cascades to foreign table "type_JSON" +drop cascades to foreign table "type_JSONB" +drop cascades to foreign table "BitT" +drop cascades to foreign table notype +drop cascades to foreign table typetest +drop cascades to foreign table "type_TEXT" +drop cascades to foreign table alltypetest +drop cascades to foreign table json_osm_test +drop cascades to foreign table shorty +drop cascades to foreign table "A a" +drop cascades to foreign table fts_table +drop cascades to foreign table fts_table_data +drop cascades to foreign table fts_table_idx +drop cascades to foreign table fts_table_content +drop cascades to foreign table fts_table_docsize +drop cascades to foreign table fts_table_config +drop cascades to foreign table "RO_RW_test" +drop cascades to foreign table "Unicode data" +drop cascades to foreign table "type_BOOLEAN_oper" +drop cascades to foreign table ret_base +drop cascades to foreign table ret_j1t +drop cascades to foreign table ret_j2t +drop cascades to foreign table type_json +drop cascades to server sqlite2 +drop cascades to server sqlite_svr_ins +drop cascades to foreign table inserttest01 +drop cascades to view inserttest01_view_wco +drop cascades to view inserttest01_view diff --git a/expected/16.3/with_gis_support/auto_import.out b/expected/16.3/with_gis_support/auto_import.out index 95055559..75b0ea12 100644 --- a/expected/16.3/with_gis_support/auto_import.out +++ b/expected/16.3/with_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/16.3/without_gis_support/auto_import.out b/expected/16.3/without_gis_support/auto_import.out index 4c399770..3e7e4546 100644 --- a/expected/16.3/without_gis_support/auto_import.out +++ b/expected/16.3/without_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/17.0/extra/returning.out b/expected/17.0/extra/returning.out new file mode 100644 index 00000000..2fe8a795 --- /dev/null +++ b/expected/17.0/extra/returning.out @@ -0,0 +1,582 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; +--Testcase 05: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 08: +SELECT * FROM "type_STRING"; + col +----- +(0 rows) + +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 13: +SELECT * FROM "type_BYTE"; + col +----- +(0 rows) + +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 16: +SELECT * FROM "type_SINT"; + col +----- +(0 rows) + +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 18: +SELECT * FROM "type_BINT"; + col +----- +(0 rows) + +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 20: +SELECT * FROM "type_INTEGER"; + col +----- +(0 rows) + +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 22: +SELECT * FROM "type_FLOAT"; + col +----- +(0 rows) + +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 24: +SELECT * FROM "type_DOUBLE"; + col +----- +(0 rows) + +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +ERROR: RETURNING clause is not supported +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; + col | b +-----+--- +(0 rows) + +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 28: +SELECT * FROM "type_BLOB"; + col +----- +(0 rows) + +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 35: +SELECT * FROM typetest; + i | v | c | t | d | ti +---+---+---+---+---+---- +(0 rows) + +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 49: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 56: +SELECT * FROM "type_DATE"; + col +----- +(0 rows) + +--Testcase 57: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +ERROR: RETURNING clause is not supported +--Testcase 60: +SELECT * FROM "type_TIME"; + col +----- +(0 rows) + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 65: +SELECT * FROM type_JSON; + col +----- +(0 rows) + +--Testcase 66: +DELETE FROM type_JSON RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +ERROR: RETURNING clause is not supported +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +ERROR: RETURNING clause is not supported +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +ERROR: RETURNING clause is not supported +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +ERROR: RETURNING clause is not supported +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +ERROR: RETURNING clause is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +ERROR: RETURNING clause is not supported +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +ERROR: RETURNING clause is not supported +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 111: +SELECT * FROM ret_base; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 113: +SELECT * FROM ret_j1t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 115: +SELECT * FROM ret_j2t; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +ERROR: RETURNING clause is not supported +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +ERROR: RETURNING clause is not supported +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; +ERROR: RETURNING clause is not supported +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +ERROR: RETURNING clause is not supported +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (10, 50, uuuuu). +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +ERROR: new row violates check option for view "inserttest01_view_wco" +DETAIL: Failing row contains (25, 40, uuuuu). +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; +ERROR: RETURNING clause is not supported +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; + QUERY PLAN +------------------------------------- + Insert on public."type_STRING" + Batch Size: 1 + Conflict Resolution: NOTHING + -> Result + Output: 'string_ocdn'::text +(5 rows) + +--Testcase 142: +DELETE FROM "type_STRING"; +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; +NOTICE: drop cascades to 62 other objects +DETAIL: drop cascades to server sqlite_svr +drop cascades to foreign table department +drop cascades to foreign table employee +drop cascades to foreign table empdata +drop cascades to foreign table numbers +drop cascades to foreign table t +drop cascades to foreign table multiprimary +drop cascades to foreign table columntest +drop cascades to foreign table noprimary +drop cascades to foreign table limittest +drop cascades to foreign table grem1_1 +drop cascades to foreign table grem1_2 +drop cascades to foreign table case_exp +drop cascades to foreign table "type_STRING" +drop cascades to foreign table "type_BOOLEANpk" +drop cascades to foreign table "type_BOOLEAN" +drop cascades to foreign table "type_BYTE" +drop cascades to foreign table "type_SINT" +drop cascades to foreign table "type_BINT" +drop cascades to foreign table "type_INTEGER" +drop cascades to foreign table "type_FLOAT" +drop cascades to foreign table "type_DOUBLE" +drop cascades to foreign table "type_TIMESTAMP" +drop cascades to foreign table "type_BLOB" +drop cascades to foreign table "type_DATE" +drop cascades to foreign table "type_TIME" +drop cascades to foreign table "type_BIT" +drop cascades to foreign table "type_VARBIT" +drop cascades to foreign table "type_UUIDpk" +drop cascades to foreign table "type_UUID" +drop cascades to foreign table "type_MACADDRpk" +drop cascades to foreign table "type_MACADDR" +drop cascades to foreign table "type_MACADDR8pk" +drop cascades to foreign table "type_MACADDR8" +drop cascades to foreign table "type_JSON" +drop cascades to foreign table "type_JSONB" +drop cascades to foreign table "BitT" +drop cascades to foreign table notype +drop cascades to foreign table typetest +drop cascades to foreign table "type_TEXT" +drop cascades to foreign table alltypetest +drop cascades to foreign table json_osm_test +drop cascades to foreign table shorty +drop cascades to foreign table "A a" +drop cascades to foreign table fts_table +drop cascades to foreign table fts_table_data +drop cascades to foreign table fts_table_idx +drop cascades to foreign table fts_table_content +drop cascades to foreign table fts_table_docsize +drop cascades to foreign table fts_table_config +drop cascades to foreign table "RO_RW_test" +drop cascades to foreign table "Unicode data" +drop cascades to foreign table "type_BOOLEAN_oper" +drop cascades to foreign table ret_base +drop cascades to foreign table ret_j1t +drop cascades to foreign table ret_j2t +drop cascades to foreign table type_json +drop cascades to server sqlite2 +drop cascades to server sqlite_svr_ins +drop cascades to foreign table inserttest01 +drop cascades to view inserttest01_view_wco +drop cascades to view inserttest01_view diff --git a/expected/17.0/with_gis_support/auto_import.out b/expected/17.0/with_gis_support/auto_import.out index 95055559..75b0ea12 100644 --- a/expected/17.0/with_gis_support/auto_import.out +++ b/expected/17.0/with_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | USER-DEFINED | public | geometry + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | geom | 4 | | YES | USER-DEFINED | public | geometry + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/expected/17.0/without_gis_support/auto_import.out b/expected/17.0/without_gis_support/auto_import.out index 4c399770..3e7e4546 100644 --- a/expected/17.0/without_gis_support/auto_import.out +++ b/expected/17.0/without_gis_support/auto_import.out @@ -71,9 +71,12 @@ SELECT * FROM ft; contrib_regression | public | RO_RW_test | contrib_regression | sqlite_svr | 51 contrib_regression | public | Unicode data | contrib_regression | sqlite_svr | 52 contrib_regression | public | type_BOOLEAN_oper | contrib_regression | sqlite_svr | 53 - contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 54 - contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 55 -(55 rows) + contrib_regression | public | ret_base | contrib_regression | sqlite_svr | 54 + contrib_regression | public | ret_j1t | contrib_regression | sqlite_svr | 55 + contrib_regression | public | ret_j2t | contrib_regression | sqlite_svr | 56 + contrib_regression | public | ♁ | contrib_regression | sqlite_svr | 57 + contrib_regression | public | ♂ | contrib_regression | sqlite_svr | 58 +(58 rows) --Testcase 07: CREATE VIEW fc AS ( @@ -232,20 +235,29 @@ SELECT n, table_name, column_name, tab_no, def, "null", data_type, udt_schema, u 53 | type_BOOLEAN_oper | b1 | 3 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | i2 | 4 | | YES | bytea | pg_catalog | bytea 53 | type_BOOLEAN_oper | b2 | 5 | | YES | bytea | pg_catalog | bytea - 54 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea - 54 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar - 54 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 - 54 | ♁ | arr | 5 | | YES | text | pg_catalog | text - 54 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb - 55 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 - 55 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar - 55 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea - 55 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date - 55 | ♂ | class | 6 | | YES | text | pg_catalog | text - 55 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar -(159 rows) + 54 | ret_base | c1 | 1 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c2 | 2 | | YES | bigint | pg_catalog | int8 + 54 | ret_base | c3 | 3 | | YES | text | pg_catalog | text + 55 | ret_j1t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 55 | ret_j1t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 56 | ret_j2t | c1 | 1 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c2 | 2 | | YES | bigint | pg_catalog | int8 + 56 | ret_j2t | c3 | 3 | | YES | double precision | pg_catalog | float8 + 57 | ♁ | geom | 1 | | NO | bytea | pg_catalog | bytea + 57 | ♁ | osm_type | 2 | | NO | character varying | pg_catalog | varchar + 57 | ♁ | osm_id | 3 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | ver | 4 | | NO | bigint | pg_catalog | int8 + 57 | ♁ | arr | 5 | | YES | text | pg_catalog | text + 57 | ♁ | t | 6 | | YES | jsonb | pg_catalog | jsonb + 58 | ♂ | id | 1 | | YES | bigint | pg_catalog | int8 + 58 | ♂ | UAI | 2 | | YES | character varying | pg_catalog | varchar + 58 | ♂ | ⌖ | 3 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | geom | 4 | | YES | bytea | pg_catalog | bytea + 58 | ♂ | t₀ | 5 | | YES | date | pg_catalog | date + 58 | ♂ | class | 6 | | YES | text | pg_catalog | text + 58 | ♂ | URL | 7 | | YES | character varying | pg_catalog | varchar +(168 rows) --Testcase 09: size/length/presision metadata SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx, num_sc, dtp FROM fc; @@ -397,20 +409,29 @@ SELECT n, table_name, column_name, tab_no, c_max_len, c_oct_len, num_pr, num_rdx 53 | type_BOOLEAN_oper | b1 | 3 | | | | | | 53 | type_BOOLEAN_oper | i2 | 4 | | | | | | 53 | type_BOOLEAN_oper | b2 | 5 | | | | | | - 54 | ♁ | geom | 1 | | | | | | - 54 | ♁ | osm_type | 2 | 16 | 64 | | | | - 54 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | - 54 | ♁ | ver | 4 | | | 64 | 2 | 0 | - 54 | ♁ | arr | 5 | | 1073741824 | | | | - 54 | ♁ | t | 6 | | | | | | - 55 | ♂ | id | 1 | | | 64 | 2 | 0 | - 55 | ♂ | UAI | 2 | 254 | 1016 | | | | - 55 | ♂ | ⌖ | 3 | | | | | | - 55 | ♂ | geom | 4 | | | | | | - 55 | ♂ | t₀ | 5 | | | | | | 0 - 55 | ♂ | class | 6 | | 1073741824 | | | | - 55 | ♂ | URL | 7 | 80 | 320 | | | | -(159 rows) + 54 | ret_base | c1 | 1 | | | 64 | 2 | 0 | + 54 | ret_base | c2 | 2 | | | 64 | 2 | 0 | + 54 | ret_base | c3 | 3 | | 1073741824 | | | | + 55 | ret_j1t | c1 | 1 | | | 64 | 2 | 0 | + 55 | ret_j1t | c2 | 2 | | | 64 | 2 | 0 | + 55 | ret_j1t | c3 | 3 | | | 53 | 2 | | + 56 | ret_j2t | c1 | 1 | | | 64 | 2 | 0 | + 56 | ret_j2t | c2 | 2 | | | 64 | 2 | 0 | + 56 | ret_j2t | c3 | 3 | | | 53 | 2 | | + 57 | ♁ | geom | 1 | | | | | | + 57 | ♁ | osm_type | 2 | 16 | 64 | | | | + 57 | ♁ | osm_id | 3 | | | 64 | 2 | 0 | + 57 | ♁ | ver | 4 | | | 64 | 2 | 0 | + 57 | ♁ | arr | 5 | | 1073741824 | | | | + 57 | ♁ | t | 6 | | | | | | + 58 | ♂ | id | 1 | | | 64 | 2 | 0 | + 58 | ♂ | UAI | 2 | 254 | 1016 | | | | + 58 | ♂ | ⌖ | 3 | | | | | | + 58 | ♂ | geom | 4 | | | | | | + 58 | ♂ | t₀ | 5 | | | | | | 0 + 58 | ♂ | class | 6 | | 1073741824 | | | | + 58 | ♂ | URL | 7 | 80 | 320 | | | | +(168 rows) --Testcase 10: other metadata SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, isgen FROM fc; @@ -562,20 +583,29 @@ SELECT n, table_name, column_name, tab_no, it, ip, max_crd, dtdid, sref, ididt, 53 | type_BOOLEAN_oper | b1 | 3 | | | | 3 | NO | NO | NEVER 53 | type_BOOLEAN_oper | i2 | 4 | | | | 4 | NO | NO | NEVER 53 | type_BOOLEAN_oper | b2 | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER - 54 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER - 54 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER - 54 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER - 54 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER - 54 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER - 55 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER - 55 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER - 55 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER - 55 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER - 55 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER - 55 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER -(159 rows) + 54 | ret_base | c1 | 1 | | | | 1 | NO | NO | NEVER + 54 | ret_base | c2 | 2 | | | | 2 | NO | NO | NEVER + 54 | ret_base | c3 | 3 | | | | 3 | NO | NO | NEVER + 55 | ret_j1t | c1 | 1 | | | | 1 | NO | NO | NEVER + 55 | ret_j1t | c2 | 2 | | | | 2 | NO | NO | NEVER + 55 | ret_j1t | c3 | 3 | | | | 3 | NO | NO | NEVER + 56 | ret_j2t | c1 | 1 | | | | 1 | NO | NO | NEVER + 56 | ret_j2t | c2 | 2 | | | | 2 | NO | NO | NEVER + 56 | ret_j2t | c3 | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | geom | 1 | | | | 1 | NO | NO | NEVER + 57 | ♁ | osm_type | 2 | | | | 2 | NO | NO | NEVER + 57 | ♁ | osm_id | 3 | | | | 3 | NO | NO | NEVER + 57 | ♁ | ver | 4 | | | | 4 | NO | NO | NEVER + 57 | ♁ | arr | 5 | | | | 5 | NO | NO | NEVER + 57 | ♁ | t | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | id | 1 | | | | 1 | NO | NO | NEVER + 58 | ♂ | UAI | 2 | | | | 2 | NO | NO | NEVER + 58 | ♂ | ⌖ | 3 | | | | 3 | NO | NO | NEVER + 58 | ♂ | geom | 4 | | | | 4 | NO | NO | NEVER + 58 | ♂ | t₀ | 5 | | | | 5 | NO | NO | NEVER + 58 | ♂ | class | 6 | | | | 6 | NO | NO | NEVER + 58 | ♂ | URL | 7 | | | | 7 | NO | NO | NEVER +(168 rows) --Testcase 11: SELECT * FROM information_schema.column_options @@ -624,7 +654,10 @@ IN (SELECT foreign_table_catalog, foreign_table_schema, foreign_table_name FROM contrib_regression | public | fts_table_config | k | key | true contrib_regression | public | RO_RW_test | i | key | true contrib_regression | public | Unicode data | i | key | true -(41 rows) + contrib_regression | public | ret_base | c1 | key | true + contrib_regression | public | ret_j1t | c1 | key | true + contrib_regression | public | ret_j2t | c1 | key | true +(44 rows) --Testcase 11: DROP VIEW fc; diff --git a/sql/13.15/extra/returning.sql b/sql/13.15/extra/returning.sql new file mode 100644 index 00000000..75b15a5d --- /dev/null +++ b/sql/13.15/extra/returning.sql @@ -0,0 +1,355 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); + +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; + +--Testcase 05: +SELECT * FROM "type_STRING"; +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 08: +SELECT * FROM "type_STRING"; +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; + +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; + +--Testcase 13: +SELECT * FROM "type_BYTE"; +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 16: +SELECT * FROM "type_SINT"; +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +--Testcase 18: +SELECT * FROM "type_BINT"; +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +--Testcase 20: +SELECT * FROM "type_INTEGER"; +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +--Testcase 22: +SELECT * FROM "type_FLOAT"; +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +--Testcase 24: +SELECT * FROM "type_DOUBLE"; +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +--Testcase 28: +SELECT * FROM "type_BLOB"; +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; + +--Testcase 35: +SELECT * FROM typetest; +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; + +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; + +--Testcase 49: +SELECT * FROM "type_DATE"; +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +--Testcase 56: +SELECT * FROM "type_DATE"; + +--Testcase 57: +SELECT * FROM "type_TIME"; +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +--Testcase 60: +SELECT * FROM "type_TIME"; + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +--Testcase 65: +SELECT * FROM type_JSON; +--Testcase 66: +DELETE FROM type_JSON RETURNING *; + +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); + +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; + +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +--Testcase 111: +SELECT * FROM ret_base; +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +--Testcase 113: +SELECT * FROM ret_j1t; +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +--Testcase 115: +SELECT * FROM ret_j2t; + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; + +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; + +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; + +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; + +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; + +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; + +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 142: +DELETE FROM "type_STRING"; + +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/14.12/extra/returning.sql b/sql/14.12/extra/returning.sql new file mode 100644 index 00000000..75b15a5d --- /dev/null +++ b/sql/14.12/extra/returning.sql @@ -0,0 +1,355 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); + +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; + +--Testcase 05: +SELECT * FROM "type_STRING"; +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 08: +SELECT * FROM "type_STRING"; +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; + +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; + +--Testcase 13: +SELECT * FROM "type_BYTE"; +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 16: +SELECT * FROM "type_SINT"; +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +--Testcase 18: +SELECT * FROM "type_BINT"; +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +--Testcase 20: +SELECT * FROM "type_INTEGER"; +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +--Testcase 22: +SELECT * FROM "type_FLOAT"; +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +--Testcase 24: +SELECT * FROM "type_DOUBLE"; +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +--Testcase 28: +SELECT * FROM "type_BLOB"; +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; + +--Testcase 35: +SELECT * FROM typetest; +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; + +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; + +--Testcase 49: +SELECT * FROM "type_DATE"; +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +--Testcase 56: +SELECT * FROM "type_DATE"; + +--Testcase 57: +SELECT * FROM "type_TIME"; +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +--Testcase 60: +SELECT * FROM "type_TIME"; + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +--Testcase 65: +SELECT * FROM type_JSON; +--Testcase 66: +DELETE FROM type_JSON RETURNING *; + +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); + +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; + +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +--Testcase 111: +SELECT * FROM ret_base; +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +--Testcase 113: +SELECT * FROM ret_j1t; +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +--Testcase 115: +SELECT * FROM ret_j2t; + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; + +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; + +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; + +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; + +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; + +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; + +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 142: +DELETE FROM "type_STRING"; + +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/15.7/extra/returning.sql b/sql/15.7/extra/returning.sql new file mode 100644 index 00000000..75b15a5d --- /dev/null +++ b/sql/15.7/extra/returning.sql @@ -0,0 +1,355 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); + +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; + +--Testcase 05: +SELECT * FROM "type_STRING"; +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 08: +SELECT * FROM "type_STRING"; +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; + +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; + +--Testcase 13: +SELECT * FROM "type_BYTE"; +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 16: +SELECT * FROM "type_SINT"; +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +--Testcase 18: +SELECT * FROM "type_BINT"; +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +--Testcase 20: +SELECT * FROM "type_INTEGER"; +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +--Testcase 22: +SELECT * FROM "type_FLOAT"; +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +--Testcase 24: +SELECT * FROM "type_DOUBLE"; +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +--Testcase 28: +SELECT * FROM "type_BLOB"; +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; + +--Testcase 35: +SELECT * FROM typetest; +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; + +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; + +--Testcase 49: +SELECT * FROM "type_DATE"; +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +--Testcase 56: +SELECT * FROM "type_DATE"; + +--Testcase 57: +SELECT * FROM "type_TIME"; +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +--Testcase 60: +SELECT * FROM "type_TIME"; + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +--Testcase 65: +SELECT * FROM type_JSON; +--Testcase 66: +DELETE FROM type_JSON RETURNING *; + +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); + +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; + +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +--Testcase 111: +SELECT * FROM ret_base; +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +--Testcase 113: +SELECT * FROM ret_j1t; +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +--Testcase 115: +SELECT * FROM ret_j2t; + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; + +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; + +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; + +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; + +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; + +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; + +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 142: +DELETE FROM "type_STRING"; + +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/16.3/extra/returning.sql b/sql/16.3/extra/returning.sql new file mode 100644 index 00000000..75b15a5d --- /dev/null +++ b/sql/16.3/extra/returning.sql @@ -0,0 +1,355 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); + +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; + +--Testcase 05: +SELECT * FROM "type_STRING"; +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 08: +SELECT * FROM "type_STRING"; +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; + +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; + +--Testcase 13: +SELECT * FROM "type_BYTE"; +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 16: +SELECT * FROM "type_SINT"; +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +--Testcase 18: +SELECT * FROM "type_BINT"; +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +--Testcase 20: +SELECT * FROM "type_INTEGER"; +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +--Testcase 22: +SELECT * FROM "type_FLOAT"; +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +--Testcase 24: +SELECT * FROM "type_DOUBLE"; +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +--Testcase 28: +SELECT * FROM "type_BLOB"; +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; + +--Testcase 35: +SELECT * FROM typetest; +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; + +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; + +--Testcase 49: +SELECT * FROM "type_DATE"; +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +--Testcase 56: +SELECT * FROM "type_DATE"; + +--Testcase 57: +SELECT * FROM "type_TIME"; +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +--Testcase 60: +SELECT * FROM "type_TIME"; + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +--Testcase 65: +SELECT * FROM type_JSON; +--Testcase 66: +DELETE FROM type_JSON RETURNING *; + +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); + +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; + +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +--Testcase 111: +SELECT * FROM ret_base; +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +--Testcase 113: +SELECT * FROM ret_j1t; +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +--Testcase 115: +SELECT * FROM ret_j2t; + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; + +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; + +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; + +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; + +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; + +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; + +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 142: +DELETE FROM "type_STRING"; + +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/17.0/extra/returning.sql b/sql/17.0/extra/returning.sql new file mode 100644 index 00000000..75b15a5d --- /dev/null +++ b/sql/17.0/extra/returning.sql @@ -0,0 +1,355 @@ +--SET log_min_messages TO DEBUG4; +--SET client_min_messages TO DEBUG4; +--Testcase 01: +CREATE EXTENSION sqlite_fdw; +--Testcase 02: +CREATE SERVER sqlite_svr FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/common.db'); + +--Testcase 03: +CREATE SERVER sqlite2 FOREIGN DATA WRAPPER sqlite_fdw; +--Testcase 04: +IMPORT FOREIGN SCHEMA main EXCEPT ("types_PostGIS", "♁", "♂") FROM SERVER sqlite_svr INTO public; + +--Testcase 05: +SELECT * FROM "type_STRING"; +--Testcase 06: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 07: +UPDATE "type_STRING" SET col = '_' || substr(col, 2) RETURNING *; +--Testcase 08: +SELECT * FROM "type_STRING"; +--Testcase 09: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_STRING" RETURNING *; +--Testcase 10: +DELETE FROM "type_STRING" RETURNING *; + +--Testcase 11: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 12: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; + +--Testcase 13: +SELECT * FROM "type_BYTE"; +--Testcase 14: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 15: +DELETE FROM "type_BYTE" RETURNING *; +--Testcase 16: +SELECT * FROM "type_SINT"; +--Testcase 17: +DELETE FROM "type_SINT" RETURNING *; +--Testcase 18: +SELECT * FROM "type_BINT"; +--Testcase 19: +DELETE FROM "type_BINT" RETURNING *; +--Testcase 20: +SELECT * FROM "type_INTEGER"; +--Testcase 21: +DELETE FROM "type_INTEGER" RETURNING *; +--Testcase 22: +SELECT * FROM "type_FLOAT"; +--Testcase 23: +DELETE FROM "type_FLOAT" RETURNING *; +--Testcase 24: +SELECT * FROM "type_DOUBLE"; +--Testcase 25: +DELETE FROM "type_DOUBLE" RETURNING *; +-- +set datestyle=ISO; +--Testcase 26: +SELECT * FROM "type_TIMESTAMP"; +--Testcase 27: +DELETE FROM "type_TIMESTAMP" RETURNING *; +--Testcase 28: +SELECT * FROM "type_BLOB"; +--Testcase 29: +DELETE FROM "type_BLOB" RETURNING *; +--Testcase 30: +ALTER TABLE "type_UUID" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 31: +DELETE FROM "type_UUID" RETURNING *; +--Testcase 32: +ALTER TABLE "type_BIT" ALTER COLUMN "i" OPTIONS (ADD key 'true'); +--Testcase 33: +ALTER TABLE "type_BIT" ALTER COLUMN b TYPE bit(6); +--Testcase 34: +DELETE FROM "type_BIT" RETURNING *; + +--Testcase 35: +SELECT * FROM typetest; +--Testcase 36: +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 37: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string') ON CONFLICT DO NOTHING RETURNING *; +--Testcase 38: +INSERT INTO "type_BYTE"(col) VALUES ('c') RETURNING *; +--Testcase 39: +INSERT INTO "type_SINT"(col) VALUES (32767) RETURNING *; +--Testcase 40: +INSERT INTO "type_SINT"(col) VALUES (-32768) RETURNING *; +--Testcase 41: +INSERT INTO "type_BINT"(col) VALUES (9223372036854775807) RETURNING *; +--Testcase 42: +INSERT INTO "type_BINT"(col) VALUES (-9223372036854775808) RETURNING *; +--Testcase 43: +INSERT INTO "type_INTEGER"(col) VALUES (9223372036854775807) RETURNING *; + +--Testcase 44: +INSERT INTO "type_FLOAT"(col) VALUES (3.1415) RETURNING *; +--Testcase 45: +INSERT INTO "type_DOUBLE"(col) VALUES (3.14159265) RETURNING *; +--Testcase 46: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 12:34:56.789', '2017.11.06') RETURNING *; +--Testcase 47: +INSERT INTO "type_TIMESTAMP" VALUES ('2017.11.06 1:3:0', '2017.11.07') RETURNING *; +--Testcase 48: +INSERT INTO "type_BLOB"(col) VALUES (bytea('\xDEADBEEF')) RETURNING *; + +--Testcase 49: +SELECT * FROM "type_DATE"; +--Testcase 50: +INSERT INTO "type_DATE"(col) VALUES ('2021.02.23') RETURNING col; +--Testcase 51: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/08') RETURNING col; +--Testcase 52: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-30') RETURNING col; +--Testcase 53: +INSERT INTO "type_DATE"(col) VALUES ('2021.04.23') RETURNING col; +--Testcase 54: +INSERT INTO "type_DATE"(col) VALUES ('2021/03/09') RETURNING col; +--Testcase 55: +INSERT INTO "type_DATE"(col) VALUES ('9999-12-29') RETURNING col; +--Testcase 56: +SELECT * FROM "type_DATE"; + +--Testcase 57: +SELECT * FROM "type_TIME"; +--Testcase 58: +INSERT INTO "type_TIME"(col) VALUES ('01:23:46') RETURNING col; +--Testcase 59: +INSERT INTO "type_TIME"(col) VALUES ('01:23:47.6789') RETURNING col; +--Testcase 60: +SELECT * FROM "type_TIME"; + +--Testcase 61: +CREATE FOREIGN TABLE type_JSON(col JSON OPTIONS (key 'true')) SERVER sqlite_svr OPTIONS (table 'type_TEXT'); +--Testcase 62 +SELECT * FROM type_JSON; +--Testcase 63: +INSERT INTO type_JSON(col) VALUES ('[1, 2, "foo", null]') RETURNING *; +--Testcase 64: +INSERT INTO type_JSON(col) VALUES ('{"bar": "baz", "balance": 7.77, "active": false}'::json) RETURNING *; +--Testcase 65: +SELECT * FROM type_JSON; +--Testcase 66: +DELETE FROM type_JSON RETURNING *; + +--Testcase 70: +ALTER TABLE typetest ALTER COLUMN i OPTIONS (ADD key 'true'); + +--Testcase 71: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 72: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +INSERT INTO typetest VALUES (1, 'a', 'b', 'c', '2017.11.06 12:34:56.789', '2017.11.06 12:34:56.789') RETURNING *; +--Testcase 73: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 74: +INSERT INTO typetest VALUES (2, 'd', 'e', 'f', '2018.11.06 12:34:56.789', '2018.11.05 12:34:56.789') RETURNING d, c, t, i, ti, v; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 76: +INSERT INTO typetest VALUES (3, 'g', 'h', 'i', '2019.11.06 12:34:56.789', '2019.11.05 12:34:56.789') RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 78: +INSERT INTO typetest VALUES (4, 'j', 'k', 'l', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING ti c_timestamp; +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; +--Testcase 80: +INSERT INTO typetest VALUES (5, 'm', 'n', 'opqrs', '2020.11.06 12:34:56.789', '2020.11.05 12:34:56.789') RETURNING substr(t, 2) sst; + +--Testcase 81: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 82: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +UPDATE typetest SET t='upd' WHERE i=1 RETURNING *; +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 86: +UPDATE typetest SET t='upd' WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 88: +UPDATE typetest SET t='upd' WHERE i=4 RETURNING ti c_timestamp; +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 90: +UPDATE typetest SET t='upd' WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 91: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 92: (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); +DELETE FROM typetest WHERE i=1 RETURNING *; +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=2 RETURNING d, c, t, i, ti, v; +--Testcase 95: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 96: +DELETE FROM typetest WHERE i=3 RETURNING d c_date, c c_char, t c_text, i c_int, ti c_timestamp, v c_varchar; +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 98: +DELETE FROM typetest WHERE i=4 RETURNING ti c_timestamp; +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; +--Testcase 100: +DELETE FROM typetest WHERE i=5 RETURNING substr(c, 2) sst; + +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +--Testcase 102: +INSERT INTO typetest VALUES (6, 'p', 'q', 'r', '2021.11.06 12:34:56.789', '2021.11.05 12:34:56.789') RETURNING 'ok' t; +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 103: +UPDATE typetest SET t='upd' WHERE i=6 RETURNING 'ok1'; +--Testcase 104: +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM typetest WHERE i=6 RETURNING 'del'; +--Testcase 105: +DELETE FROM typetest WHERE i=6 RETURNING 'del'; + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 110: +INSERT INTO ret_base (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id RETURNING *; +--Testcase 111: +SELECT * FROM ret_base; +--Testcase 112: +INSERT INTO ret_j1t (c1, c2, c3) VALUES (8, 5, 14.2), (7, 2, -14.3), (12, 3, 0.001), (9, 3, -0.5) RETURNING *; +--Testcase 113: +SELECT * FROM ret_j1t; +--Testcase 114: +INSERT INTO ret_j2t (c1, c2, c3) VALUES (8, 18, 5.8), (7, 41, 2.1), (12, 28, -0.09), (9, 14, +17.4) RETURNING *; +--Testcase 115: +SELECT * FROM ret_j2t; + +--Testcase 116: +UPDATE ret_base SET c3 = 'foo+' RETURNING ret_base.*, ret_base; + +--Testcase 117: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; -- can be pushed down +--Testcase 118: +UPDATE ret_base SET c3 = 'foo' + FROM ret_j1t INNER JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c2 = ret_j1t.c1 + RETURNING ret_base, ret_base.*, ret_j1t, ret_j1t.*; +--Testcase 119: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; -- can be pushed down +--Testcase 120: +DELETE FROM ret_base + USING ret_j1t LEFT JOIN ret_j2t ON (ret_j1t.c1 = ret_j2t.c1) + WHERE ret_base.c1 > 1200 AND ret_base.c1 % 10 = 0 AND ret_base.c2 = ret_j1t.c1 + RETURNING 100; + +--Testcase 121: +DELETE FROM ret_base RETURNING ret_base.*, ret_base; + +--Testcase 122: Test that trigger on remote table works as expected +CREATE OR REPLACE FUNCTION F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 123: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON ret_base FOR EACH ROW EXECUTE PROCEDURE F_BRTRIG(); +--Testcase 124: +INSERT INTO ret_base (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; +--Testcase 125: +INSERT INTO ret_base (c1,c2,c3) VALUES (1218, 818, 'ggg') RETURNING *; +--Testcase 126: +EXPLAIN (verbose, costs off) +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; +--Testcase 127: +UPDATE ret_base SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1300 RETURNING *; + +--Testcase 128: +EXPLAIN (verbose, costs off) +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; +--Testcase 129: +DELETE FROM ret_base WHERE ret_base.c1 > 1200 RETURNING ret_base.*, ret_base; + +--Testcase 130: +CREATE SERVER sqlite_svr_ins FOREIGN DATA WRAPPER sqlite_fdw +OPTIONS (database '/tmp/sqlite_fdw_test/core.db'); +--Testcase 131: +CREATE FOREIGN TABLE inserttest01 (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER sqlite_svr_ins; +--Testcase 132: +CREATE VIEW inserttest01_view_wco AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50 +WITH CHECK OPTION; +--Testcase 133: +CREATE VIEW inserttest01_view AS +SELECT * FROM inserttest01 WHERE col1 > 20 AND col2 = 50; +--Testcase 134: ok +INSERT INTO inserttest01_view values(10, 40, 'uuuuu'); +--Testcase 135: no! +INSERT INTO inserttest01_view_wco values(10, 50, 'uuuuu'); +--Testcase 136: no! +INSERT INTO inserttest01_view_wco values(25, 40, 'uuuuu'); +--Testcase 137: ok +INSERT INTO inserttest01_view values(11, 42, 'uuuuu') RETURNING *; +--Testcase 138: +ALTER TABLE inserttest01 ALTER COLUMN col1 OPTIONS (ADD key 'true'); +--Testcase 139: +DELETE FROM inserttest01 RETURNING *; + +--Testcase 140: +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO "type_STRING"(col) VALUES ('string_ocdn') ON CONFLICT DO NOTHING; +--Testcase 142: +DELETE FROM "type_STRING"; + +--Testcase 200: +DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/init_data/init.sql b/sql/init_data/init.sql index 2ef29391..fa4193f9 100644 --- a/sql/init_data/init.sql +++ b/sql/init_data/init.sql @@ -65,7 +65,7 @@ CREATE VIEW "type_JSONB+" AS SELECT FROM "type_JSONB"; CREATE TABLE BitT (p integer primary key, a BIT(3), b BIT VARYING(5)); CREATE TABLE notype (a); -CREATE TABLE typetest (i integer, v varchar(10) , c char(10), t text, d datetime, ti timestamp); +CREATE TABLE typetest (i integer, v varchar(10), c char(10), t text, d datetime, ti timestamp); CREATE TABLE type_TEXT (col text primary key); CREATE TABLE alltypetest ( c1 int, @@ -113,7 +113,7 @@ CREATE TABLE "A a" (col int primary key); -- test for issue #44 github CREATE VIRTUAL TABLE fts_table USING fts5(name, description, tokenize = porter); --- updatable option test (github pull 59) +-- updatable + force_readonly options test CREATE TABLE RO_RW_test ( i int primary key not null, a text, @@ -158,6 +158,11 @@ WITH booldata AS ( ) SELECT ROW_NUMBER() OVER () i, t1.i i1, t1.b b1, t2.i i2, t2.b b2 FROM booldata t1 INNER JOIN booldata t2 ON 1; +-- RETURNING for UPDATE/DELETE ... FROM ret_base JOIN ret_j1t JOIN ret_j2t +CREATE TABLE ret_base (c1 int primary key, c2 int, c3 text); +CREATE TABLE ret_j1t (c1 int primary key, c2 int, c3 float); +CREATE TABLE ret_j2t (c1 int primary key, c2 int, c3 float); + -- SpatiaLite/PostGIS test -- This table name also tests SpatiaLite and PostGIS metadata functions. Made as analog of the next "martian" table. CREATE TABLE "♁" ( diff --git a/sqlite_data_norm.c b/sqlite_data_norm.c index adf6ada0..457ec5f3 100644 --- a/sqlite_data_norm.c +++ b/sqlite_data_norm.c @@ -46,7 +46,7 @@ if (count != MACADDR8_LEN) \ /* * This UUID SQLite extension as a group of UUID C functions * implements functions that handling RFC-4122 UUIDs - * Three SQL functions are implemented: + * Following SQL functions are implemented: * * sqlite_fdw_uuid_str(X) - convert a UUID X into a well-formed UUID string * sqlite_fdw_uuid_blob(X) - convert a UUID X into a 16-byte blob @@ -94,9 +94,10 @@ if (count != MACADDR8_LEN) \ */ /* - * Translate a single byte of Hex into an integer. - * This routine only works if h really is a valid hexadecimal - * character: 0..9a..fA..F + * sqlite_fdw_data_norm_UuidHexToInt + * Translate a single byte of Hex into an integer. + * This routine only works if h really is a valid hexadecimal + * character: 0..9a..fA..F */ static unsigned char sqlite_fdw_data_norm_UuidHexToInt(int h) @@ -112,12 +113,13 @@ sqlite_fdw_data_norm_UuidHexToInt(int h) } /* - * Attempt to parse a zero-terminated input string zs into a binary - * UUID. Return 1 on success, or 0 if the input string is not - * parsable. + * sqlite_fdw_uuid_blob + * Attempt to parse a zero-terminated input string zs into a binary + * UUID. Return 1 on success, or 0 if the input string is not + * parsable. */ static int -sqlite_fdw_uuid_blob (const unsigned char* s0, unsigned char* Blob) +sqlite_fdw_uuid_blob (const unsigned char* s0, unsigned char* pBlob) { int i; unsigned char* s = (unsigned char*)s0; @@ -129,7 +131,7 @@ sqlite_fdw_uuid_blob (const unsigned char* s0, unsigned char* Blob) s++; if (isxdigit(s[0]) && isxdigit(s[1])) { - Blob[i] = (sqlite_fdw_data_norm_UuidHexToInt(s[0]) << 4) + sqlite_fdw_data_norm_UuidHexToInt(s[1]); + pBlob[i] = (sqlite_fdw_data_norm_UuidHexToInt(s[0]) << 4) + sqlite_fdw_data_norm_UuidHexToInt(s[1]); s += 2; } else @@ -143,7 +145,8 @@ sqlite_fdw_uuid_blob (const unsigned char* s0, unsigned char* Blob) } /* - * uuid_generate generates a version 4 UUID as a string + * uuid_generate + * generates a version 4 UUID as a string * *static void uuid_generate(sqlite3_context* context, int argc, sqlite3_value** argv) *{ @@ -158,9 +161,9 @@ sqlite_fdw_uuid_blob (const unsigned char* s0, unsigned char* Blob) */ /* - * aBlob to RFC UUID string with 36 characters + * sqlite3UuidBlobToStr + * aBlob to RFC UUID string with 36 characters */ - static void sqlite3UuidBlobToStr( const unsigned char *aBlob, unsigned char *zs) { @@ -182,8 +185,9 @@ sqlite3UuidBlobToStr( const unsigned char *aBlob, unsigned char *zs) } /* - * Converts argument BLOB-UUID into a well-formed UUID string. - * X can be either a string or a blob. + * sqlite_fdw_uuid_str + * Converts argument BLOB-UUID into a well-formed UUID string. + * X can be either a string or a blob. */ static void sqlite_fdw_uuid_str(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -220,7 +224,8 @@ sqlite_fdw_uuid_str(sqlite3_context* context, int argc, sqlite3_value** argv) } /* - * sqlite_fdw_data_norm_uuid normalize text or blob UUID argv[0] into a 16-byte blob. + * sqlite_fdw_data_norm_uuid + * normalize text or blob UUID argv[0] into a 16-byte blob. */ static void sqlite_fdw_data_norm_uuid(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -243,8 +248,9 @@ sqlite_fdw_data_norm_uuid(sqlite3_context* context, int argc, sqlite3_value** ar /* ********************* End of UUID SQLite extension *********************** */ /* - * ISO:SQL valid boolean values with text affinity such as Y, no, f, t, oN etc. - * will be treated as boolean like in PostgreSQL console input + * sqlite_fdw_data_norm_bool + * ISO:SQL valid boolean values with text affinity such as Y, no, f, t, oN etc. + * will be treated as boolean like in PostgreSQL console input */ static void sqlite_fdw_data_norm_bool(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -354,7 +360,8 @@ const char * infs = "Inf"; const char * infl = "Infinity"; /* - * Try to check SQLite value if there is any ∞ value with text affinity + * infinity_processing + * Try to check SQLite value if there is any ∞ value with text affinity */ static bool infinity_processing (double* d, const char* t) @@ -382,10 +389,11 @@ infinity_processing (double* d, const char* t) } /* - * ISO:SQL valid float/double precision values with text affinity such as Infinity or Inf - * will be treated as float like in PostgreSQL console input - * Note: SQLite also have Infinity support with real affinity, but this values - * isn't suitable for insert, there is any overflow number instead + * sqlite_fdw_data_norm_float + * ISO:SQL valid float/double precision values with text affinity such as Infinity or Inf + * will be treated as float like in PostgreSQL console input + * Note: SQLite also have Infinity support with real affinity, but this values + * isn't suitable for insert, there is any overflow number instead */ static void sqlite_fdw_data_norm_float(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -425,7 +433,8 @@ sqlite_fdw_data_norm_float(sqlite3_context* context, int argc, sqlite3_value** a } /* - * Converts argument int64-MAC address into a well-formed MAC address string. + * sqlite_fdw_macaddr_str + * Converts argument int64-MAC address into a well-formed MAC address string. */ static void sqlite_fdw_macaddr_str(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -483,12 +492,13 @@ sqlite_fdw_macaddr_str(sqlite3_context* context, int argc, sqlite3_value** argv) } /* - * Attempt to parse a zero-terminated input string zs into a int64 - * as 6 bytes MAC address. Return 1 if ok, or 0 if the input string is not - * parsable. + * sqlite_fdw_macaddr6_int + * Attempt to parse a zero-terminated input string zs into a int64 + * as 6 bytes MAC address. Return 1 if ok, or 0 if the input string is not + * parsable. */ static int -sqlite_fdw_macaddr6_int (const unsigned char* s, sqlite_uint64* i) +sqlite_fdw_macaddr6_int(const unsigned char* s, sqlite_uint64* i) { int a, b, @@ -529,12 +539,13 @@ sqlite_fdw_macaddr6_int (const unsigned char* s, sqlite_uint64* i) } /* - * Attempt to parse a zero-terminated input string zs into a int64 - * as 8 bytes MAC address. Return 1 if ok, or 0 if the input string is not - * parsable. + * sqlite_fdw_macaddr8_int + * Attempt to parse a zero-terminated input string zs into a int64 + * as 8 bytes MAC address. Return 1 if ok, or 0 if the input string is not + * parsable. */ static int -sqlite_fdw_macaddr8_int (const unsigned char* s, sqlite_uint64* i) +sqlite_fdw_macaddr8_int(const unsigned char* s, sqlite_uint64* i) { int a, b, @@ -581,7 +592,8 @@ sqlite_fdw_macaddr8_int (const unsigned char* s, sqlite_uint64* i) } /* - * sqlite_fdw_data_norm_macaddr normalize text or ineger or blob macaddr argv[0] into 6 or 8 byte blob. + * sqlite_fdw_data_norm_macaddr + * normalize text or ineger or blob macaddr argv[0] into sqlite3_uint64. */ static void sqlite_fdw_data_norm_macaddr(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -661,7 +673,9 @@ sqlite_fdw_data_norm_macaddr(sqlite3_context* context, int argc, sqlite3_value** } /* - * Converts argument int-MAC address (both 6 or 8 bytes) to MAC-BLOB address integer. + * sqlite_fdw_macaddr_blob + * Converts argument MAC address (both 6 or 8 bytes) with integer + * affinity to similar MAC address with BLOB affinity. */ static void sqlite_fdw_macaddr_blob(sqlite3_context* context, int argc, sqlite3_value** argv) @@ -714,8 +728,9 @@ sqlite_fdw_macaddr_blob(sqlite3_context* context, int argc, sqlite3_value** argv } /* - * Makes pg error from SQLite error. - * Interrupts normal executing, no need return after place of calling + * error_catcher + * Makes pg error from SQLite error. + * Interrupts normal executing, no need return after place of calling */ static void error_catcher(sqlite3* db, int rc) @@ -733,9 +748,10 @@ error_catcher(sqlite3* db, int rc) } /* - * Add data normalization fuctions to SQLite internal namespace for calling - * in deparse context. - * This is main function of internal SQLite extension presented in this file. + * sqlite_fdw_data_norm_functs_init + * Add data normalization fuctions to SQLite internal namespace for calling + * in deparse context. + * This is main function of internal SQLite extension presented in this file. */ void sqlite_fdw_data_norm_functs_init(sqlite3* db) diff --git a/sqlite_fdw.c b/sqlite_fdw.c index bfa56787..0f7b47ba 100644 --- a/sqlite_fdw.c +++ b/sqlite_fdw.c @@ -125,25 +125,33 @@ enum FdwScanPrivateIndex FdwScanPrivateRelations, }; -/* - * Similarly, this enum describes what's kept in the fdw_private list for - * a ModifyTable node referencing a sqlite_fdw foreign table. We store: - * - * 1) INSERT/UPDATE/DELETE statement text to be sent to the remote server - * 2) Integer list of target attribute numbers for INSERT/UPDATE - * (NIL for a DELETE) - * 3) Length till the end of VALUES clause for INSERT - * (-1 for a DELETE/UPDATE) - */ + /* + * Similarly, this enum describes what's kept in the fdw_private list for + * a ModifyTable node referencing a postgres_fdw foreign table. We store: + * + * 1) INSERT/UPDATE/DELETE statement text to be sent to the remote server + * 2) Integer list of target attribute numbers for INSERT/UPDATE + * (NIL for a DELETE) + * 3) Length till the end of VALUES clause for INSERT + * (-1 for a DELETE/UPDATE) Pg 14+ + * 4) Boolean flag showing if the remote query has a RETURNING clause + * 5) Integer list of attribute numbers retrieved by RETURNING, if any + */ enum FdwModifyPrivateIndex -{ - /* SQL statement to execute remotely (as a String node) */ - FdwModifyPrivateUpdateSql, - /* Integer list of target attribute numbers for INSERT/UPDATE */ - FdwModifyPrivateTargetAttnums, - /* Length till the end of VALUES clause (as an Integer node) */ - FdwModifyPrivateLen, -}; + { + /* SQL statement to execute remotely (as a String node) */ + FdwModifyPrivateUpdateSql, + /* Integer list of target attribute numbers for INSERT/UPDATE */ + FdwModifyPrivateTargetAttnums, +#if (PG_VERSION_NUM >= 140000) + /* Length till the end of VALUES clause (as an Integer node) */ + FdwModifyPrivateLen, +#endif + /* has-returning flag (as a Boolean node) */ + FdwModifyPrivateHasReturning, + /* Integer list of attribute numbers retrieved by RETURNING */ + FdwModifyPrivateRetrievedAttrs, + }; /* * Similarly, this enum describes what's kept in the fdw_private list for @@ -294,8 +302,7 @@ static void sqliteGetForeignJoinPaths(PlannerInfo *root, JoinType jointype, JoinPathExtraData *extra); -static void - sqliteGetForeignUpperPaths(PlannerInfo *root, +static void sqliteGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel @@ -311,7 +318,7 @@ static void sqlite_prepare_wrapper(ForeignServer *server, bool is_cache); static void sqlite_to_pg_type(StringInfo str, char *typname); -static TupleTableSlot **sqlite_execute_insert(EState *estate, +static TupleTableSlot **sqlite_execute_foreign_modify (EState *estate, ResultRelInfo *resultRelInfo, CmdType operation, TupleTableSlot **slots, @@ -518,7 +525,7 @@ sqlite_prepare_wrapper(ForeignServer *server, sqlite3 * db, char *query, sqlite3 { int rc; - elog(DEBUG1, "sqlite_fdw : %s %s\n", __func__, query); + elog(DEBUG1, "sqlite_fdw : %s \nSQL ->> %s", __func__, query); rc = sqlite3_prepare_v2(db, query, -1, stmt, pzTail); if (rc != SQLITE_OK) { @@ -532,7 +539,6 @@ sqlite_prepare_wrapper(ForeignServer *server, sqlite3 * db, char *query, sqlite3 sqlite_cache_stmt(server, stmt); } - /* * sqliteGetForeignRelSize: Create a FdwPlan for a scan on the foreign table */ @@ -967,7 +973,7 @@ sqliteGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, List *retrieved_attrs; ListCell *lc; List *fdw_recheck_quals = NIL; - int for_update; + int for_data_change = false; elog(DEBUG1, "sqlite_fdw : %s", __func__); @@ -982,7 +988,6 @@ sqliteGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, #if PG_VERSION_NUM >= 150000 has_final_sort = boolVal(list_nth(best_path->fdw_private, FdwPathPrivateHasFinalSort)); has_limit = boolVal(list_nth(best_path->fdw_private, FdwPathPrivateHasLimit)); - #else has_final_sort = intVal(list_nth(best_path->fdw_private, FdwPathPrivateHasFinalSort)); has_limit = intVal(list_nth(best_path->fdw_private, FdwPathPrivateHasLimit)); @@ -1169,20 +1174,23 @@ sqliteGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, /* Remember remote_exprs for possible use by sqlitePlanDirectModify */ fpinfo->final_remote_exprs = remote_exprs; - for_update = false; - if (root->parse->commandType == CMD_UPDATE || - root->parse->commandType == CMD_DELETE || - root->parse->commandType == CMD_INSERT) + if (root->parse->commandType == CMD_INSERT || + root->parse->commandType == CMD_UPDATE || + root->parse->commandType == CMD_DELETE) { - /* Relation is UPDATE/DELETE target, so use FOR UPDATE */ - for_update = true; + /* Relation is INSERT/UPDATE/DELETE target, so use FOR UPDATE */ + for_data_change = true; } /* * Build the fdw_private list that will be available to the executor. * Items in the list must match enum FdwScanPrivateIndex, above. */ - fdw_private = list_make3(makeString(sql.data), retrieved_attrs, makeInteger(for_update)); +#if PG_VERSION_NUM >= 150000 + fdw_private = list_make3(makeString(sql.data), retrieved_attrs, makeBoolean(for_data_change)); +#else + fdw_private = list_make3(makeString(sql.data), retrieved_attrs, makeInteger(for_data_change)); +#endif #if (PG_VERSION_NUM < 100000) fdw_private = lappend(fdw_private, makeInteger(root->all_baserels == NULL ? -2 : bms_next_member(root->all_baserels, -1))); #endif @@ -1322,7 +1330,11 @@ sqliteBeginForeignScan(ForeignScanState *node, int eflags) /* Stash away the state info we have already */ festate->query = strVal(list_nth(fsplan->fdw_private, FdwScanPrivateSelectSql)); festate->retrieved_attrs = list_nth(fsplan->fdw_private, FdwScanPrivateRetrievedAttrs); - festate->for_update = intVal(list_nth(fsplan->fdw_private, FdwScanPrivateForUpdate)) ? true : false; +#if PG_VERSION_NUM >= 150000 + festate->for_data_change = boolVal(list_nth(fsplan->fdw_private, FdwScanPrivateForUpdate)); +#else + festate->for_data_change = intVal(list_nth(fsplan->fdw_private, FdwScanPrivateForUpdate)) ? true : false; +#endif festate->conn = conn; festate->cursor_exists = false; @@ -1366,30 +1378,62 @@ sqliteBeginForeignScan(ForeignScanState *node, int eflags) &festate->param_types); } +/* + * Create a tuple from the current state of sqlite3_stmt. + * + * rel is the local representation of the foreign table, attinmeta is + * conversion data for the rel's tupdesc + * + * Note: either rel or node, but not both, can be NULL. rel is NULL + * if we're processing a remote join, while node is NULL in a non-query + * context such as ANALYZE, or if we're processing a non-scan query node. + */ static void -make_tuple_from_result_row(sqlite3_stmt * stmt, - TupleDesc tupleDescriptor, - List *retrieved_attrs, - Datum *row, - bool *is_null, - SqliteFdwExecState * festate, - ForeignScanState *node) +sqlite_make_tuple_from_result_row(sqlite3_stmt * stmt, + Relation rel, + AttInMetadata *attinmeta, + List *retrieved_attrs, + ForeignScanState *node, + Datum *values, + bool *nulls +) { + TupleDesc tupdesc; + /*Datum *values; + bool *nulls;*/ ConversionLocation errpos; ErrorContextCallback errcallback; - ListCell *lc = NULL; + ListCell *lc = NULL; int stmt_colid = 0; - NullableDatum sqlite_coverted; + NullableDatum sqlite_converted; - memset(row, 0, sizeof(Datum) * tupleDescriptor->natts); - memset(is_null, true, sizeof(bool) * tupleDescriptor->natts); + /* + * Get the tuple descriptor for the row. Use the rel's tupleDescriptor if rel is + * provided, otherwise look to the scan node's ScanTupleSlot. + */ + if (rel) + tupdesc = RelationGetDescr(rel); + else + { + Assert(node); + tupdesc = node->ss.ss_ScanTupleSlot->tts_tupleDescriptor; + } + + /* + *values = (Datum *) palloc0(tupdesc->natts * sizeof(Datum)); + *nulls = (bool *) palloc(tupdesc->natts * sizeof(bool)); + */ + /* Initialize to nulls for any columns not present in result */ + memset(nulls, true, tupdesc->natts * sizeof(bool)); + + memset(values, 0, tupdesc->natts * sizeof(Datum) ); /* * Set up and install callback to report where conversion error occurs. */ errpos.cur_attno = 0; errpos.att = NULL; - errpos.rel = festate->rel; + errpos.rel = rel; errpos.fsstate = node; errpos.val = NULL; errcallback.callback = conversion_error_callback; @@ -1400,13 +1444,12 @@ make_tuple_from_result_row(sqlite3_stmt * stmt, foreach(lc, retrieved_attrs) { int attnum = lfirst_int(lc) - 1; - Form_pg_attribute att = TupleDescAttr(tupleDescriptor, attnum); - sqlite3_value *val = sqlite3_column_value(stmt, stmt_colid); - int sqlite_value_affinity = sqlite3_value_type(val); + int sqlite_value_affinity = SQLITE_NULL; + errpos.att = TupleDescAttr(tupdesc, attnum); errpos.cur_attno = attnum; - errpos.att = att; - errpos.val = val; + errpos.val = sqlite3_column_value(stmt, stmt_colid); + sqlite_value_affinity = sqlite3_value_type(errpos.val); if ( sqlite_value_affinity != SQLITE_NULL) { /* TODO: Processing of column options about special convert behaviour @@ -1418,16 +1461,13 @@ make_tuple_from_result_row(sqlite3_stmt * stmt, * Flags about special convert behaviour from options on database, table or column level */ - sqlite_coverted = sqlite_convert_to_pg(att, val, - festate->attinmeta, - attnum, sqlite_value_affinity, - AffinityBehaviourFlags); - if (!sqlite_coverted.isnull) { - is_null[attnum] = false; - row[attnum] = sqlite_coverted.value; - } - else - is_null[attnum] = true; + sqlite_converted = sqlite_convert_to_pg(errpos.att, errpos.val, + attinmeta, + attnum, sqlite_value_affinity, + AffinityBehaviourFlags); + nulls[attnum] = sqlite_converted.isnull; + if (!sqlite_converted.isnull) + values[attnum] = sqlite_converted.value; } stmt_colid++; } @@ -1447,8 +1487,8 @@ sqliteIterateForeignScan(ForeignScanState *node) EState *estate = node->ss.ps.state; TupleDesc tupleDescriptor = tupleSlot->tts_tupleDescriptor; int rc = 0; - - elog(DEBUG1, "sqlite_fdw : %s", __func__); + int values_size = sizeof(Datum) * tupleDescriptor->natts; + int isnull_size = sizeof(bool) * tupleDescriptor->natts; /* * If this is the first call after Begin or ReScan, we need to create the @@ -1457,22 +1497,23 @@ sqliteIterateForeignScan(ForeignScanState *node) if (!festate->cursor_exists) sqlite_create_cursor(node); - ExecClearTuple(tupleSlot); /* - * We get all rows before starting update if this scan is for update - * because there is no isolation between update and select on the same - * database connections. Please see for details: + * We get all rows before starting update if this scan is for + * DML (data change) because there is no isolation between + * DML and select (DSL) on the same database connections. + * Please see for details: * https://sqlite.org/isolation.html */ - if (festate->for_update && festate->rowidx == 0) + if (festate->for_data_change && festate->rowidx == 0) { int size = 0; - /* festate->rows need longer context than per tuple */ + /* festate->rows_values need longer context than per tuple */ MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + elog(DEBUG2, "sqlite_fdw : %s for update, festate->rowidx == 0", __func__); festate->row_nums = 0; festate->rowidx = 0; while (1) @@ -1480,31 +1521,29 @@ sqliteIterateForeignScan(ForeignScanState *node) rc = sqlite3_step(festate->stmt); if (rc == SQLITE_ROW) { - if (size == 0) { size = 1; - festate->rows = palloc(sizeof(Datum *) * size); + festate->rows_values = palloc(sizeof(Datum *) * size); festate->rows_isnull = palloc(sizeof(bool *) * size); } else if (festate->row_nums >= size) { /* expand array */ size = size * 2; - festate->rows = repalloc(festate->rows, sizeof(Datum *) * size); + festate->rows_values = repalloc(festate->rows_values, sizeof(Datum *) * size); festate->rows_isnull = repalloc(festate->rows_isnull, sizeof(bool *) * size); } - festate->rows[festate->row_nums] = palloc(sizeof(Datum) * tupleDescriptor->natts); - festate->rows_isnull[festate->row_nums] = palloc(sizeof(bool) * tupleDescriptor->natts); - make_tuple_from_result_row(festate->stmt, - tupleDescriptor, festate->retrieved_attrs, - festate->rows[festate->row_nums], - festate->rows_isnull[festate->row_nums], - festate, - node); - + festate->rows_values[festate->row_nums] = palloc(values_size); + festate->rows_isnull[festate->row_nums] = palloc(isnull_size); + sqlite_make_tuple_from_result_row(festate->stmt, + festate->rel, + festate->attinmeta, + festate->retrieved_attrs, + node, + festate->rows_values[festate->row_nums], + festate->rows_isnull[festate->row_nums]); festate->row_nums++; - } else if (SQLITE_DONE == rc) { @@ -1513,34 +1552,35 @@ sqliteIterateForeignScan(ForeignScanState *node) } else { - sqlitefdw_report_error(ERROR, festate->stmt, festate->conn, NULL, rc); + sqlitefdw_report_error(ERROR, festate->stmt, festate->conn, __func__, rc); } } MemoryContextSwitchTo(oldcontext); } - if (festate->for_update) + if (festate->for_data_change) { if (festate->rowidx < festate->row_nums) { - memcpy(tupleSlot->tts_values, festate->rows[festate->rowidx], sizeof(Datum) * tupleDescriptor->natts); - memcpy(tupleSlot->tts_isnull, festate->rows_isnull[festate->rowidx], sizeof(bool) * tupleDescriptor->natts); + memcpy(tupleSlot->tts_values, festate->rows_values[festate->rowidx], values_size); + memcpy(tupleSlot->tts_isnull, festate->rows_isnull[festate->rowidx], isnull_size); ExecStoreVirtualTuple(tupleSlot); festate->rowidx++; } } else { + elog(DEBUG2, "sqlite_fdw : %s, NO DML", __func__); rc = sqlite3_step(festate->stmt); if (SQLITE_ROW == rc) { - make_tuple_from_result_row(festate->stmt, - tupleDescriptor, - festate->retrieved_attrs, - tupleSlot->tts_values, - tupleSlot->tts_isnull, - festate, - node); + sqlite_make_tuple_from_result_row(festate->stmt, + festate->rel, + festate->attinmeta, + festate->retrieved_attrs, + node, + tupleSlot->tts_values, + tupleSlot->tts_isnull); ExecStoreVirtualTuple(tupleSlot); } else if (SQLITE_DONE == rc) @@ -1549,7 +1589,7 @@ sqliteIterateForeignScan(ForeignScanState *node) } else { - sqlitefdw_report_error(ERROR, festate->stmt, festate->conn, NULL, rc); + sqlitefdw_report_error(ERROR, festate->stmt, festate->conn, __func__, rc); } } return tupleSlot; @@ -1686,14 +1726,17 @@ sqlitePlanForeignModify(PlannerInfo *root, CmdType operation = plan->operation; RangeTblEntry *rte = planner_rt_fetch(resultRelation, root); Relation rel; - List *targetAttrs = NULL; StringInfoData sql; + List *targetAttrs = NULL; + List *withCheckOptionList = NIL; + List *returningList = NIL; + List *retrieved_attrs = NIL; + bool doNothing = false; + int values_end_len = -1; Oid foreignTableId; TupleDesc tupdesc; int i; - List *condAttr = NULL; - bool doNothing = false; - int values_end_len = -1; + List *conditionAttr = NULL; elog(DEBUG1, "sqlite_fdw : %s", __func__); @@ -1753,6 +1796,19 @@ sqlitePlanForeignModify(PlannerInfo *root, } } + /* + * Extract the relevant WITH CHECK OPTION list if any. + */ + if (plan->withCheckOptionLists) + withCheckOptionList = (List *) list_nth(plan->withCheckOptionLists, + subplan_index); + + /* + * Extract the relevant RETURNING list if any. + * + * after RETURNING implememntation here should be + * returningList = (List *) list_nth(plan->returningLists, subplan_index); + */ if (plan->returningLists) ereport(ERROR, (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), @@ -1771,8 +1827,8 @@ sqlitePlanForeignModify(PlannerInfo *root, (int) plan->onConflictAction); /* - * Add all primary key attribute names to condAttr used in where clause of - * update + * Add all primary key attribute names to conditionAttr used in where clause of + * update and delete */ for (i = 0; i < tupdesc->natts; ++i) { @@ -1789,7 +1845,7 @@ sqlitePlanForeignModify(PlannerInfo *root, if (IS_KEY_COLUMN(def)) { - condAttr = lappend_int(condAttr, attrno); + conditionAttr = lappend_int(conditionAttr, attrno); } } } @@ -1800,20 +1856,56 @@ sqlitePlanForeignModify(PlannerInfo *root, switch (operation) { case CMD_INSERT: - sqlite_deparse_insert(&sql, root, resultRelation, rel, targetAttrs, doNothing, &values_end_len); + sqlite_deparseInsertSql(&sql, root, resultRelation, rel, + targetAttrs, doNothing, + withCheckOptionList, returningList, + &retrieved_attrs, &values_end_len); break; case CMD_UPDATE: - sqlite_deparse_update(&sql, root, resultRelation, rel, targetAttrs, condAttr); + sqlite_deparseUpdateSql(&sql, root, resultRelation, rel, + targetAttrs, + withCheckOptionList, returningList, + &retrieved_attrs, + conditionAttr); break; case CMD_DELETE: - sqlite_deparse_delete(&sql, root, resultRelation, rel, condAttr); + sqlite_deparseDeleteSql(&sql, root, resultRelation, rel, + returningList, + &retrieved_attrs, + conditionAttr); break; default: elog(ERROR, "unexpected operation: %d", (int) operation); break; } + table_close(rel, NoLock); - return list_make3(makeString(sql.data), targetAttrs, makeInteger(values_end_len)); + + /* + * Build the fdw_private list that will be available to the executor. + * Items in the list must match enum FdwModifyPrivateIndex, above. + */ +#if (PG_VERSION_NUM >= 140000) + return list_make5(makeString(sql.data), + targetAttrs, + makeInteger(values_end_len), + #if (PG_VERSION_NUM >= 150000) + makeBoolean((retrieved_attrs != NIL)), + #else + makeInteger((retrieved_attrs != NIL)), + #endif + retrieved_attrs); +#else + /*return list_make4(makeString(sql.data), + targetAttrs, + makeInteger(values_end_len), + retrieved_attrs);*/ + return list_make4(makeString(sql.data), + targetAttrs, + makeInteger((retrieved_attrs != NIL)), + retrieved_attrs); + +#endif } static void @@ -1826,17 +1918,16 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, SqliteFdwExecState *fmstate = NULL; EState *estate = mtstate->ps.state; Relation rel = resultRelInfo->ri_RelationDesc; + TupleDesc tupdesc = RelationGetDescr(rel); AttrNumber n_params = 0; Oid typefnoid = InvalidOid; bool isvarlena = false; ListCell *lc = NULL; - Oid foreignTableId = InvalidOid; + Oid foreignTableId = RelationGetRelid(rel); Plan *subplan; int i; elog(DEBUG1, "sqlite_fdw : %s", __func__); - - foreignTableId = RelationGetRelid(rel); #if (PG_VERSION_NUM >= 140000) subplan = outerPlanState(mtstate)->plan; #else @@ -1858,11 +1949,20 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, fmstate->conn = sqlite_get_connection(fmstate->server, false); fmstate->query = strVal(list_nth(fdw_private, FdwModifyPrivateUpdateSql)); fmstate->target_attrs = (List *) list_nth(fdw_private, FdwModifyPrivateTargetAttnums); - fmstate->retrieved_attrs = (List *) list_nth(fdw_private, FdwModifyPrivateTargetAttnums); +#if PG_VERSION_NUM >= 150000 + fmstate->has_returning = boolVal(list_nth(fdw_private, FdwModifyPrivateHasReturning)); +#else + fmstate->has_returning = intVal(list_nth(fdw_private, FdwModifyPrivateHasReturning)); +#endif + fmstate->retrieved_attrs = (List *) list_nth(fdw_private, FdwModifyPrivateRetrievedAttrs); +#if PG_VERSION_NUM >= 140000 fmstate->values_end = intVal(list_nth(fdw_private, FdwModifyPrivateLen)); +#else + fmstate->values_end = -1; +#endif fmstate->orig_query = pstrdup(fmstate->query); - n_params = list_length(fmstate->retrieved_attrs) + 1; + n_params = list_length(fmstate->target_attrs) + 1; fmstate->p_flinfo = (FmgrInfo *) palloc0(sizeof(FmgrInfo) * n_params); fmstate->p_nums = 0; fmstate->temp_cxt = AllocSetContextCreate(estate->es_query_cxt, @@ -1871,8 +1971,12 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE); + /* Prepare for input conversion of RETURNING results. */ + if (fmstate->has_returning) + fmstate->attinmeta = TupleDescGetAttInMetadata(tupdesc); + /* Set up for remaining transmittable parameters */ - foreach(lc, fmstate->retrieved_attrs) + foreach(lc, fmstate->target_attrs) { int attnum = lfirst_int(lc); Form_pg_attribute attr = TupleDescAttr(RelationGetDescr(rel), attnum - 1); @@ -1882,7 +1986,7 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, /* Ignore generated columns; */ if (attr->attgenerated) { - if (list_length(fmstate->retrieved_attrs) >= 1) + if (list_length(fmstate->target_attrs) >= 1) fmstate->p_nums = 1; continue; } @@ -1898,7 +2002,7 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, fmstate->batch_size = sqlite_get_batch_size_option(rel); #endif - n_params = list_length(fmstate->retrieved_attrs); + n_params = list_length(fmstate->target_attrs); /* Initialize sqlite statment */ fmstate->stmt = NULL; @@ -1924,8 +2028,8 @@ sqliteBeginForeignModify(ModifyTableState *mtstate, #endif )); } - } + #if (PG_VERSION_NUM >= 110000) static void sqliteBeginForeignInsert(ModifyTableState *mtstate, @@ -1933,12 +2037,14 @@ sqliteBeginForeignInsert(ModifyTableState *mtstate, { elog(ERROR, "Not support partition insert"); } + static void sqliteEndForeignInsert(EState *estate, ResultRelInfo *resultRelInfo) { elog(ERROR, "Not support partition insert"); } + #endif /* * sqliteExecForeignInsert @@ -1953,7 +2059,7 @@ sqliteExecForeignInsert(EState *estate, TupleTableSlot **rslot; int numSlots = 1; - rslot = sqlite_execute_insert(estate, resultRelInfo, CMD_INSERT, + rslot = sqlite_execute_foreign_modify (estate, resultRelInfo, CMD_INSERT, &slot, &planSlot, &numSlots); return rslot ? *rslot : NULL; @@ -1973,7 +2079,7 @@ sqliteExecForeignBatchInsert(EState *estate, { TupleTableSlot **rslot; - rslot = sqlite_execute_insert(estate, resultRelInfo, CMD_INSERT, + rslot = sqlite_execute_foreign_modify (estate, resultRelInfo, CMD_INSERT, slots, planSlots, numSlots); return rslot; @@ -2134,6 +2240,136 @@ sqlite_find_modifytable_subplan(PlannerInfo *root, } #endif +/* + * sqlite_build_remote_returning + * Build a RETURNING targetlist of a remote query for performing an + * UPDATE/DELETE .. RETURNING on a join directly + */ +static List * +sqlite_build_remote_returning(Index rtindex, Relation rel, List *returningList) +{ + bool have_wholerow = false; + List *tlist = NIL; + List *vars; + ListCell *lc; + + Assert(returningList); + + vars = pull_var_clause((Node *) returningList, PVC_INCLUDE_PLACEHOLDERS); + + /* + * If there's a whole-row reference to the target relation, then we'll + * need all the columns of the relation. + */ + foreach(lc, vars) + { + Var *var = (Var *) lfirst(lc); + + if (IsA(var, Var) && + var->varno == rtindex && + var->varattno == InvalidAttrNumber) + { + have_wholerow = true; + break; + } + } + + if (have_wholerow) + { + TupleDesc tupdesc = RelationGetDescr(rel); + int i; + + for (i = 1; i <= tupdesc->natts; i++) + { + Form_pg_attribute attr = TupleDescAttr(tupdesc, i - 1); + Var *var; + + /* Ignore dropped attributes. */ + if (attr->attisdropped) + continue; + + var = makeVar(rtindex, + i, + attr->atttypid, + attr->atttypmod, + attr->attcollation, + 0); + + tlist = lappend(tlist, + makeTargetEntry((Expr *) var, + list_length(tlist) + 1, + NULL, + false)); + } + } + + /* Now add any remaining columns to tlist. */ + foreach(lc, vars) + { + Var *var = (Var *) lfirst(lc); + + /* + * No need for whole-row references to the target relation. We don't + * need system columns other than ctid and oid either, since those are + * set locally. + */ + if (IsA(var, Var) && + var->varno == rtindex && + var->varattno <= InvalidAttrNumber && + var->varattno != SelfItemPointerAttributeNumber) + continue; /* don't need it */ + + if (tlist_member((Expr *) var, tlist)) + continue; /* already got it */ + + tlist = lappend(tlist, + makeTargetEntry((Expr *) var, + list_length(tlist) + 1, + NULL, + false)); + } + + list_free(vars); + + return tlist; +} + + +/* + * rebuild_fdw_scan_tlist + * Build new fdw_scan_tlist of given foreign-scan plan node from given + * tlist + * + * There might be columns that the fdw_scan_tlist of the given foreign-scan + * plan node contains that the given tlist doesn't. The fdw_scan_tlist would + * have contained resjunk columns such as 'ctid' of the target relation and + * 'wholerow' of non-target relations, but the tlist might not contain them, + * for example. So, adjust the tlist so it contains all the columns specified + * in the fdw_scan_tlist; else setrefs.c will get confused. + */ +static void +rebuild_fdw_scan_tlist(ForeignScan *fscan, List *tlist) +{ + List *new_tlist = tlist; + List *old_tlist = fscan->fdw_scan_tlist; + ListCell *lc; + + foreach(lc, old_tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + + if (tlist_member(tle->expr, new_tlist)) + continue; /* already got it */ + + new_tlist = lappend(new_tlist, + makeTargetEntry(tle->expr, + list_length(new_tlist) + 1, + NULL, + false)); + } + fscan->fdw_scan_tlist = new_tlist; +} + /* * sqlitePlanDirectModify * Consider a direct foreign table modification @@ -2163,6 +2399,7 @@ sqlitePlanDirectModify(PlannerInfo *root, List *targetAttrs = NIL; List *remote_exprs; List *params_list = NIL; + List *returningList = NIL; List *retrieved_attrs = NIL; elog(DEBUG1, "sqlite_fdw : %s", __func__); @@ -2203,11 +2440,8 @@ sqlitePlanDirectModify(PlannerInfo *root, #endif return false; - /* not supported RETURNING clause by this FDW */ if (plan->returningLists) - { - return false; - } + return false; /* still not supported RETURNING clause by this FDW */ /* Safe to fetch data about the target foreign rel */ if (fscan->scan.scanrelid == 0) @@ -2310,13 +2544,34 @@ sqlitePlanDirectModify(PlannerInfo *root, */ remote_exprs = fpinfo->final_remote_exprs; + /* + * Extract the relevant RETURNING list if any. + */ + if (plan->returningLists) + { + returningList = (List *) list_nth(plan->returningLists, subplan_index); + + /* + * When performing an UPDATE/DELETE .. RETURNING on a join directly, + * we fetch from the foreign server any Vars specified in RETURNING + * that refer not only to the target relation but to non-target + * relations. So we'll deparse them into the RETURNING clause of the + * remote query; use a targetlist consisting of them instead, which + * will be adjusted to be new fdw_scan_tlist of the foreign-scan plan + * node below. + */ + if (fscan->scan.scanrelid == 0) + returningList = sqlite_build_remote_returning(resultRelation, rel, + returningList); + } + /* * Construct the SQL command string. */ switch (operation) { case CMD_UPDATE: - sqlite_deparse_direct_update_sql(&sql, root, resultRelation, rel, + sqlite_deparseDirectUpdateSql(&sql, root, resultRelation, rel, foreignrel, #if (PG_VERSION_NUM >= 140000) processed_tlist, @@ -2325,13 +2580,13 @@ sqlitePlanDirectModify(PlannerInfo *root, #endif targetAttrs, remote_exprs, ¶ms_list, - &retrieved_attrs); + returningList, &retrieved_attrs); break; case CMD_DELETE: - sqlite_deparse_direct_delete_sql(&sql, root, resultRelation, rel, + sqlite_deparseDirectDeleteSql(&sql, root, resultRelation, rel, foreignrel, remote_exprs, ¶ms_list, - &retrieved_attrs); + returningList, &retrieved_attrs); break; default: elog(ERROR, "unexpected operation: %d", (int) operation); @@ -2373,12 +2628,98 @@ sqlitePlanDirectModify(PlannerInfo *root, { /* No need for the outer subplan. */ fscan->scan.plan.lefttree = NULL; + + /* Build new fdw_scan_tlist if UPDATE/DELETE .. RETURNING. */ + if (returningList) + rebuild_fdw_scan_tlist(fscan, returningList); } +#if PG_VERSION_NUM >= 150000 + /* + * Finally, unset the async-capable flag if it is set, as we currently + * don't support asynchronous execution of direct modifications. + */ + if (fscan->scan.plan.async_capable) + fscan->scan.plan.async_capable = false; +#endif + table_close(rel, NoLock); return true; } +/* + * Initialize a filter to extract an updated/deleted tuple from a scan tuple. + */ +static void +sqlite_init_returning_filter(SqliteFdwDirectModifyState *dmstate, + List *fdw_scan_tlist, + Index rtindex) +{ + TupleDesc resultTupType = RelationGetDescr(dmstate->resultRel); + ListCell *lc; + int i; + + /* + * Calculate the mapping between the fdw_scan_tlist's entries and the + * result tuple's attributes. + * + * The "map" is an array of indexes of the result tuple's attributes in + * fdw_scan_tlist, i.e., one entry for every attribute of the result + * tuple. We store zero for any attributes that don't have the + * corresponding entries in that list, marking that a NULL is needed in + * the result tuple. + * + * Also get the indexes of the entries for ctid and oid if any. + */ + dmstate->attnoMap = (AttrNumber *) + palloc0(resultTupType->natts * sizeof(AttrNumber)); + + dmstate->ctidAttno = dmstate->oidAttno = 0; + + i = 1; + dmstate->hasSystemCols = false; + foreach(lc, fdw_scan_tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + Var *var = (Var *) tle->expr; + + Assert(IsA(var, Var)); + + /* + * If the Var is a column of the target relation to be retrieved from + * the foreign server, get the index of the entry. + */ + if (var->varno == rtindex && + list_member_int(dmstate->retrieved_attrs, i)) + { + int attrno = var->varattno; + + if (attrno < 0) + { + /* + * We don't retrieve system columns other than ctid and oid. + */ + if (attrno == SelfItemPointerAttributeNumber) + dmstate->ctidAttno = i; + else + Assert(false); + dmstate->hasSystemCols = true; + } + else + { + /* + * We don't retrieve whole-row references to the target + * relation either. + */ + Assert(attrno > 0); + + dmstate->attnoMap[attrno - 1] = i; + } + } + i++; + } +} + /* * sqliteBeginDirectModify * Prepare a direct foreign table modification @@ -2437,7 +2778,7 @@ sqliteBeginDirectModify(ForeignScanState *node, int eflags) /* * Set dmstate->rel to NULL to teach get_returning_data() and - * make_tuple_from_result_row() that columns fetched from the remote + * sqlite_make_tuple_from_result_row() that columns fetched from the remote * server are described by fdw_scan_tlist of the foreign-scan plan * node, not the tuple descriptor for the target relation. */ @@ -2469,6 +2810,31 @@ sqliteBeginDirectModify(ForeignScanState *node, int eflags) "sqlite_fdw temporary data", ALLOCSET_SMALL_SIZES); + /* Prepare for input conversion of RETURNING results. */ + if (dmstate->has_returning) + { + TupleDesc tupdesc; + + if (fsplan->scan.scanrelid == 0) +#if (PG_VERSION_NUM >= 140000) + tupdesc = sqlite_get_tupdesc_for_join_scan_tuples(node); +#else + tupdesc = node->ss.ss_ScanTupleSlot->tts_tupleDescriptor; +#endif + else + tupdesc = RelationGetDescr(dmstate->rel); + + dmstate->attinmeta = TupleDescGetAttInMetadata(tupdesc); + + /* + * When performing an UPDATE/DELETE .. RETURNING on a join directly, + * initialize a filter to extract an updated/deleted tuple from a scan + * tuple. + */ + if (fsplan->scan.scanrelid == 0) + sqlite_init_returning_filter(dmstate, fsplan->fdw_scan_tlist, rtindex); + } + /* Initialize the SQLite statement */ dmstate->stmt = NULL; @@ -2490,6 +2856,162 @@ sqliteBeginDirectModify(ForeignScanState *node, int eflags) &dmstate->param_types); } +/* + * Extract and return an updated/deleted tuple from a scan tuple. + */ +static TupleTableSlot * +apply_returning_filter(SqliteFdwDirectModifyState *dmstate, + ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, + EState *estate) +{ + TupleDesc resultTupType = RelationGetDescr(dmstate->resultRel); + TupleTableSlot *resultSlot; + Datum *values; + bool *isnull; + Datum *old_values; + bool *old_isnull; + int i; + + /* + * Use the return tuple slot as a place to store the result tuple. + */ + resultSlot = ExecGetReturningSlot(estate, resultRelInfo); + + /* + * Extract all the values of the scan tuple. + */ + slot_getallattrs(slot); + old_values = slot->tts_values; + old_isnull = slot->tts_isnull; + + /* + * Prepare to build the result tuple. + */ + ExecClearTuple(resultSlot); + values = resultSlot->tts_values; + isnull = resultSlot->tts_isnull; + + /* + * Transpose data into proper fields of the result tuple. + */ + for (i = 0; i < resultTupType->natts; i++) + { + int j = dmstate->attnoMap[i]; + + if (j == 0) + { + values[i] = (Datum) 0; + isnull[i] = true; + } + else + { + values[i] = old_values[j - 1]; + isnull[i] = old_isnull[j - 1]; + } + } + + /* + * Build the virtual tuple. + */ + ExecStoreVirtualTuple(resultSlot); + + /* + * We have no system columns to return. + */ + + /* + * And return the result tuple. + */ + return resultSlot; +} + +/* + * Get the result of a RETURNING clause. + */ +static TupleTableSlot * +get_returning_data(ForeignScanState *node) +{ + SqliteFdwDirectModifyState *dmstate = (SqliteFdwDirectModifyState *) node->fdw_state; + EState *estate = node->ss.ps.state; +#if (PG_VERSION_NUM >= 140000) + ResultRelInfo *resultRelInfo = node->resultRelInfo; +#else + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; +#endif + TupleTableSlot *tupleSlot = node->ss.ss_ScanTupleSlot; + TupleTableSlot *resultSlot; + + Assert(resultRelInfo->ri_projectReturning); + + /* If we didn't get any tuples, must be end of data. */ + if (dmstate->next_tuple >= dmstate->num_tuples) + return ExecClearTuple(tupleSlot); + + elog(DEBUG2, "sqlite_fdw : %s", __func__); + + /* Increment the command es_processed count if necessary. */ + if (dmstate->set_processed) + estate->es_processed += 1; + + /* + * Store a RETURNING tuple. If has_returning is false, just emit a dummy + * tuple. (has_returning is false when the local query is of the form + * "UPDATE/DELETE .. RETURNING 1" for example.) + */ + if (!dmstate->has_returning) + { + ExecStoreAllNullTuple(tupleSlot); + resultSlot = tupleSlot; + } + else + { + AttInMetadata *attinmeta = TupleDescGetAttInMetadata(tupleSlot->tts_tupleDescriptor); + + /* + * On error, be sure to release the PGresult on the way out. Callers + * do not have PG_TRY blocks to ensure this happens. + */ + PG_TRY(); + { + HeapTuple tuple; + sqlite_make_tuple_from_result_row(dmstate->stmt, + dmstate->rel, + attinmeta, + dmstate->retrieved_attrs, + node, + tupleSlot->tts_values, + tupleSlot->tts_isnull); + tuple = heap_form_tuple(tupleSlot->tts_tupleDescriptor, tupleSlot->tts_values, tupleSlot->tts_isnull); + + HeapTupleHeaderSetXmax(tuple->t_data, InvalidTransactionId); + HeapTupleHeaderSetXmin(tuple->t_data, InvalidTransactionId); + HeapTupleHeaderSetCmin(tuple->t_data, InvalidTransactionId); + + ExecStoreHeapTuple(tuple, tupleSlot, false); + } + PG_CATCH(); + { + /* reset? dmstate->stmt; */ + PG_RE_THROW(); + } + PG_END_TRY(); + + /* Get the updated/deleted tuple. */ + if (dmstate->rel) + resultSlot = tupleSlot; + else + resultSlot = apply_returning_filter(dmstate, resultRelInfo, tupleSlot, estate); + } + dmstate->next_tuple++; + + /* Make slot available for evaluation of the local query RETURNING list. */ + resultRelInfo->ri_projectReturning->pi_exprContext->ecxt_scantuple = + resultSlot; + + return tupleSlot; +} + /* * sqliteIterateDirectModify * Execute a direct foreign table modification @@ -2498,29 +3020,46 @@ static TupleTableSlot * sqliteIterateDirectModify(ForeignScanState *node) { SqliteFdwDirectModifyState *dmstate = (SqliteFdwDirectModifyState *) node->fdw_state; - EState *estate = node->ss.ps.state; - TupleTableSlot *slot = node->ss.ss_ScanTupleSlot; - Instrumentation *instr = node->ss.ps.instrument; + EState *estate = node->ss.ps.state; +#if (PG_VERSION_NUM >= 140000) + ResultRelInfo *resultRelInfo = node->resultRelInfo; +#else + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; +#endif elog(DEBUG1, "sqlite_fdw : %s", __func__); - Assert(!dmstate->has_returning); - /* * If this is the first call after Begin, execute the statement. */ if (dmstate->num_tuples == -1) sqlite_execute_dml_stmt(node); - /* Increment the command es_processed count if necessary. */ - if (dmstate->set_processed) - estate->es_processed += dmstate->num_tuples; + /* + * If the local query doesn't specify RETURNING, just clear tuple slot. + */ + if (!resultRelInfo->ri_projectReturning) + { + TupleTableSlot *slot = node->ss.ss_ScanTupleSlot; + Instrumentation *instr = node->ss.ps.instrument; + + Assert(!dmstate->has_returning); + + /* Increment the command es_processed count if necessary. */ + if (dmstate->set_processed) + estate->es_processed += dmstate->num_tuples; - /* Increment the tuple count for EXPLAIN ANALYZE if necessary. */ - if (instr) - instr->tuplecount += dmstate->num_tuples; + /* Increment the tuple count for EXPLAIN ANALYZE if necessary. */ + if (instr) + instr->tuplecount += dmstate->num_tuples; - return ExecClearTuple(slot); + return ExecClearTuple(slot); + } + + /* + * Get the next RETURNING tuple. + */ + return get_returning_data(node); } /* @@ -2714,53 +3253,14 @@ sqliteExecForeignUpdate(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - SqliteFdwExecState *fmstate = (SqliteFdwExecState *) resultRelInfo->ri_FdwState; - Relation rel = resultRelInfo->ri_RelationDesc; - Oid foreignTableId = RelationGetRelid(rel); - ListCell *lc = NULL; - int bindnum = 0; - int i = 0; - int rc = 0; + TupleTableSlot **rslot; + int numSlots = 1; elog(DEBUG1, "sqlite_fdw : %s", __func__); + rslot = sqlite_execute_foreign_modify(estate, resultRelInfo, CMD_UPDATE, + &slot, &planSlot, &numSlots); - /* Bind the values */ - foreach(lc, fmstate->retrieved_attrs) - { - int attnum = lfirst_int(lc); - bool is_null; - Datum value = 0; - Form_pg_attribute bind_att = NULL; -#if PG_VERSION_NUM >= 140000 - TupleDesc tupdesc = RelationGetDescr(fmstate->rel); - Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); - - /* Ignore generated columns and skip bind value */ - if (attr->attgenerated) - continue; -#endif - /* first attribute cannot be in target list attribute */ - bind_att = TupleDescAttr(slot->tts_tupleDescriptor, attnum - 1); - value = slot_getattr(slot, attnum, &is_null); - - sqlite_bind_sql_var(bind_att, bindnum, value, fmstate->stmt, &is_null, foreignTableId); - bindnum++; - i++; - } - - bindJunkColumnValue(fmstate, slot, planSlot, foreignTableId, bindnum); - - /* Execute the query */ - rc = sqlite3_step(fmstate->stmt); - if (rc != SQLITE_DONE) - { - sqlitefdw_report_error(ERROR, fmstate->stmt, fmstate->conn, NULL, rc); - } - - sqlite3_reset(fmstate->stmt); - - /* Return NULL if nothing was updated on the remote end */ - return slot; + return rslot ? rslot[0] : NULL; } static TupleTableSlot * @@ -2769,24 +3269,14 @@ sqliteExecForeignDelete(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - SqliteFdwExecState *fmstate = (SqliteFdwExecState *) resultRelInfo->ri_FdwState; - Relation rel = resultRelInfo->ri_RelationDesc; - Oid foreignTableId = RelationGetRelid(rel); - int rc = 0; + TupleTableSlot **rslot; + int numSlots = 1; elog(DEBUG1, "sqlite_fdw : %s", __func__); + rslot = sqlite_execute_foreign_modify(estate, resultRelInfo, CMD_DELETE, + &slot, &planSlot, &numSlots); - bindJunkColumnValue(fmstate, slot, planSlot, foreignTableId, 0); - - /* Execute the query */ - rc = sqlite3_step(fmstate->stmt); - if (rc != SQLITE_DONE) - { - sqlitefdw_report_error(ERROR, fmstate->stmt, fmstate->conn, NULL, rc); - } - sqlite3_reset(fmstate->stmt); - /* Return NULL if nothing was updated on the remote end */ - return slot; + return rslot ? rslot[0] : NULL; } static void @@ -2923,7 +3413,6 @@ sqliteImportForeignSchema(ImportForeignSchemaStmt *stmt, /* Scan all rows for this table */ for (;;) { - char *table; char *query; bool first_item = true; @@ -3004,7 +3493,6 @@ sqliteImportForeignSchema(ImportForeignSchemaStmt *stmt, elog(DEBUG1, "sqlite_fdw : %s %s", __func__, pstrdup(buf.data)); } - } PG_CATCH(); { @@ -3174,13 +3662,13 @@ sqlite_foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype } /* - * sqlite_deparse_explicit_target_list() isn't smart enough to handle + * sqlite_deparseExplicitTargetList() isn't smart enough to handle * anything other than a Var. In particular, if there's some * PlaceHolderVar that would need to be evaluated within this join tree * (because there's an upper reference to a quantity that may go to NULL * as a result of an outer join), then we can't try to push the join down * because we'll fail when we get to - * sqlite_deparse_explicit_target_list(). However, a PlaceHolderVar that + * sqlite_deparseExplicitTargetList(). However, a PlaceHolderVar that * needs to be evaluated *at the top* of this join tree is OK, because we * can do that locally after fetching the results from the remote side. */ @@ -4989,11 +5477,53 @@ sqlite_reset_transmission_modes(int nestlevel) } /* - * sqlite_execute_insert - * Perform execute sqliteExecForeignInsert, sqliteExecForeignBatchInsert + * sqlite_foreign_modify_bind used for variables in insert and update + */ +static int sqlite_foreign_modify_bind (SqliteFdwExecState *fmstate, TupleTableSlot *slot, Relation rel) +{ + ListCell *lc = NULL; + Datum value = 0; + int bindnum = 0; + Oid foreignTableId = RelationGetRelid(rel); + /* Bind the values */ + foreach(lc, fmstate->target_attrs) + { + int attnum = lfirst_int(lc); + Form_pg_attribute att = TupleDescAttr(slot->tts_tupleDescriptor, attnum - 1); + bool is_null; +#if PG_VERSION_NUM >= 140000 + /* Ignore generated columns and skip bind value */ + if (att->attgenerated) + continue; +#endif + /* first attribute cannot be in target list attribute */ + value = slot_getattr(slot, attnum, &is_null); + sqlite_bind_sql_var(att, bindnum, value, fmstate->stmt, &is_null, foreignTableId); + bindnum++; + } + return bindnum; +} + +/* + * store_returning_result + * Store the result of a RETURNING clause + * NOT IMPLEMENTED + */ +static void +sqlite_store_returning_result(SqliteFdwExecState *fmstate, + TupleTableSlot *tupleSlot) +{ +} + +/* + * sqlite_execute_foreign_modify + * Perform foreign-table modification as required, and fetch RETURNING + * result if any. (This is the shared guts of sqliteExecForeignInsert, + * sqliteExecForeignBatchInsert, sqliteExecForeignUpdate, and + * sqliteExecForeignDelete.) */ static TupleTableSlot ** -sqlite_execute_insert(EState *estate, +sqlite_execute_foreign_modify (EState *estate, ResultRelInfo *resultRelInfo, CmdType operation, TupleTableSlot **slots, @@ -5001,38 +5531,36 @@ sqlite_execute_insert(EState *estate, int *numSlots) { SqliteFdwExecState *fmstate = (SqliteFdwExecState *) resultRelInfo->ri_FdwState; - ListCell *lc; - Datum value = 0; MemoryContext oldcontext; int rc = SQLITE_OK; int nestlevel; - int bindnum = 0; - int i; Relation rel = resultRelInfo->ri_RelationDesc; Oid foreignTableId = RelationGetRelid(rel); -#if PG_VERSION_NUM >= 140000 - TupleDesc tupdesc = RelationGetDescr(rel); -#endif elog(DEBUG1, "sqlite_fdw : %s for RelId %u", __func__, foreignTableId); + /* The operation should be INSERT, UPDATE, or DELETE */ + Assert(operation == CMD_INSERT || + operation == CMD_UPDATE || + operation == CMD_DELETE); - oldcontext = MemoryContextSwitchTo(fmstate->temp_cxt); - - nestlevel = sqlite_set_transmission_modes(); - - Assert(operation == CMD_INSERT); + if (operation == CMD_INSERT) + { + oldcontext = MemoryContextSwitchTo(fmstate->temp_cxt); + nestlevel = sqlite_set_transmission_modes(); + } #if PG_VERSION_NUM >= 140000 - if (fmstate->num_slots != *numSlots) + /* + * If the existing query was deparsed and prepared for a different number + * of rows, rebuild it for the proper number. + */ + if (operation == CMD_INSERT && fmstate->num_slots != *numSlots) { StringInfoData sql; - - fmstate->table = GetForeignTable(RelationGetRelid(fmstate->rel)); - fmstate->server = GetForeignServer(fmstate->table->serverid); fmstate->stmt = NULL; initStringInfo(&sql); - sqlite_rebuild_insert(&sql, fmstate->rel, fmstate->orig_query, + sqlite_rebuild_insert(&sql, rel, fmstate->orig_query, fmstate->target_attrs, fmstate->values_end, fmstate->p_nums, *numSlots - 1); fmstate->query = sql.data; @@ -5040,40 +5568,49 @@ sqlite_execute_insert(EState *estate, sqlite_prepare_wrapper(fmstate->server, fmstate->conn, fmstate->query, &fmstate->stmt, NULL, true); } - #endif - for (i = 0; i < *numSlots; i++) + if (operation == CMD_INSERT) { - foreach(lc, fmstate->retrieved_attrs) + int i = 0; + for (i = 0; i < *numSlots; i++) { - int attnum = lfirst_int(lc) - 1; - Form_pg_attribute att = TupleDescAttr(slots[i]->tts_tupleDescriptor, attnum); - bool isnull; -#if PG_VERSION_NUM >= 140000 - Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum); + sqlite_foreign_modify_bind (fmstate, slots[0], rel); + } + sqlite_reset_transmission_modes(nestlevel); + } - /* Ignore generated columns and skip bind value */ - if (attr->attgenerated) - continue; -#endif + if (operation == CMD_DELETE) + { + bindJunkColumnValue(fmstate, slots[0], planSlots[0], foreignTableId, 0); + } - value = slot_getattr(slots[i], attnum + 1, &isnull); - sqlite_bind_sql_var(att, bindnum, value, fmstate->stmt, &isnull, foreignTableId); - bindnum++; - } + if (operation == CMD_UPDATE) + { + int bindnum = sqlite_foreign_modify_bind (fmstate, slots[0], rel); + bindJunkColumnValue(fmstate, slots[0], planSlots[0], foreignTableId, bindnum); } - sqlite_reset_transmission_modes(nestlevel); /* Execute the query */ rc = sqlite3_step(fmstate->stmt); - if (rc != SQLITE_DONE) + if (!fmstate->has_returning && SQLITE_DONE != rc) { sqlitefdw_report_error(ERROR, fmstate->stmt, fmstate->conn, NULL, rc); } - sqlite3_reset(fmstate->stmt); - MemoryContextSwitchTo(oldcontext); - MemoryContextReset(fmstate->temp_cxt); + /* Check number of rows affected, and fetch RETURNING tuple if any */ + if (fmstate->has_returning) + { + Assert(*numSlots == 1); + if (SQLITE_ROW == rc) + sqlite_store_returning_result(fmstate, slots[0]); + } + sqlite3_reset(fmstate->stmt); + if (operation == CMD_INSERT) + { + MemoryContextSwitchTo(oldcontext); + MemoryContextReset(fmstate->temp_cxt); + } + /* Return NULL if nothing was updated on the remote end */ return slots; } @@ -5141,19 +5678,19 @@ sqlite_process_query_params(ExprContext *econtext, Oid foreignTableId ) { - int i; + int i = 0; ListCell *lc; - int nestlevel; + int nestlevel = sqlite_set_transmission_modes(); + + elog(DEBUG2, "sqlite_fdw : %s", __func__); - nestlevel = sqlite_set_transmission_modes(); - i = 0; foreach(lc, param_exprs) { - ExprState *expr_state = (ExprState *) lfirst(lc); - Datum expr_value; - bool isNull; + ExprState *expr_state = (ExprState *) lfirst(lc); + Datum expr_value; + bool isNull; /* fake structure, bind function usually works with attribute, but just typid in our case */ - Form_pg_attribute att = NULL; + Form_pg_attribute att = NULL; /* Evaluate the parameter expression */ #if PG_VERSION_NUM >= 100000 @@ -5231,6 +5768,7 @@ sqlite_execute_dml_stmt(ForeignScanState *node) Oid foreignTableId = RelationGetRelid(dmstate->rel); int rc; + elog(DEBUG2, "sqlite_fdw : %s, foreignTableOid = %d", __func__, foreignTableId); /* * Construct array of query parameter values in text format. */ @@ -5251,7 +5789,7 @@ sqlite_execute_dml_stmt(ForeignScanState *node) * server has the same OIDs we do for the parameters' types. */ rc = sqlite3_step(dmstate->stmt); - if (rc != SQLITE_DONE) + if (!dmstate->has_returning && rc != SQLITE_DONE) { sqlitefdw_report_error(ERROR, dmstate->stmt, dmstate->conn, NULL, rc); } @@ -5296,7 +5834,6 @@ sqlite_find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel) sqlite_is_foreign_expr(root, rel, em->em_expr)) return em; } - return NULL; } diff --git a/sqlite_fdw.h b/sqlite_fdw.h index 8e109bae..d9c6958a 100644 --- a/sqlite_fdw.h +++ b/sqlite_fdw.h @@ -161,12 +161,13 @@ typedef struct SQLiteFdwExecState List *attr_list; /* query attribute list */ List *column_list; /* Column list of SQLite Column structures */ + bool has_returning; /* true if there is RETURNING */ int64 row_nums; /* number of rows */ - Datum **rows; /* all rows of scan */ + Datum **rows_values; /* all rows of scan */ int64 rowidx; /* current index of rows */ bool **rows_isnull; /* is null */ - bool for_update; /* true if this scan is update target */ + bool for_data_change;/* true if this scan is data change (DML) target */ int batch_size; /* value of FDW option "batch_size" */ /* working memory context */ @@ -277,6 +278,7 @@ typedef struct SqliteFdwDirectModifyState Relation rel; /* relcache entry for the foreign table */ AttInMetadata *attinmeta; /* attribute datatype conversion metadata */ + bool has_Returning; /* is there a RETURNING clause? */ /* extracted fdw_private data */ char *query; /* text of UPDATE/DELETE command */ @@ -352,26 +354,48 @@ extern void sqlite_deparse_select_stmt_for_rel(StringInfo buf, PlannerInfo *root List *tlist, List *remote_conds, List *pathkeys, bool has_final_sort, bool has_limit, bool is_subquery, List **retrieved_attrs, List **params_list); -extern void sqlite_deparse_insert(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *targetAttrs, bool doNothing, int *values_end_len); +extern void sqlite_deparseInsertSql(StringInfo buf, + PlannerInfo *root, + Index rtindex, + Relation rel, + List *targetAttrs, + bool doNothing, + List *withCheckOptionList, + List *returningList, + List **retrieved_attrs, + int *values_end_len); #if PG_VERSION_NUM >= 140000 extern void sqlite_rebuild_insert(StringInfo buf, Relation rel, char *orig_query, List *target_attrs, int values_end_len, int num_params, int num_rows); extern void sqlite_deparse_truncate(StringInfo buf, List *rels); #endif -extern void sqlite_deparse_update(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *targetAttrs, List *attname); -extern void sqlite_deparse_direct_update_sql(StringInfo buf, PlannerInfo *root, +extern void sqlite_deparseUpdateSql(StringInfo buf, PlannerInfo *root, + Index rtindex, Relation rel, + List *targetAttrs, + List *withCheckOptionList, List *returningList, + List **retrieved_attrs, + List *condAttr); +extern void sqlite_deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, RelOptInfo *foreignrel, List *targetlist, List *targetAttrs, List *remote_conds, List **params_list, + List *returningList, List **retrieved_attrs); -extern void sqlite_deparse_delete(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *name); -extern void sqlite_deparse_direct_delete_sql(StringInfo buf, PlannerInfo *root, +extern void sqlite_deparseDeleteSql(StringInfo buf, + PlannerInfo *root, + Index rtindex, + Relation rel, + List *returningList, + List **retrieved_attrs, + List *condAttr); +extern void sqlite_deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, RelOptInfo *foreignrel, List *remote_conds, List **params_list, + List *returningList, List **retrieved_attrs); extern void sqlite_deparse_analyze(StringInfo buf, char *dbname, char *relname); extern void sqlite_deparse_string_literal(StringInfo buf, const char *val); diff --git a/sqlite_query.c b/sqlite_query.c index 20602919..8da3b1e5 100644 --- a/sqlite_query.c +++ b/sqlite_query.c @@ -65,11 +65,16 @@ pg_column_void_text_error() } /* - * convert_sqlite_to_pg + * convert_sqlite_to_pg: * Converts SQLite value into PostgreSQL's Datum */ NullableDatum -sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata *attinmeta, AttrNumber attnum, int sqlite_value_affinity, int AffinityBehaviourFlags) +sqlite_convert_to_pg(Form_pg_attribute att, + sqlite3_value * val, + AttInMetadata *attinmeta, + AttrNumber attnum, + int sqlite_value_affinity, + int AffinityBehaviourFlags) { Oid pgtyp = att->atttypid; Datum value_datum = 0; @@ -396,6 +401,10 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * sqlite_value_to_pg_error(); break; } + /* + * SQLite UUID output always normalized to blob. + * In sqlite_data_norm.c there is special additional C function. + */ case SQLITE_BLOB: /* <-- proper and recommended SQLite affinity of value for pgtyp */ { if (value_byte_size_blob_or_utf8 != UUID_LEN) @@ -404,21 +413,16 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * errmsg("PostgreSQL uuid data type allows only %d bytes SQLite blob value", UUID_LEN))); break; } - else + else { - const unsigned char * sqlite_blob = 0; pg_uuid_t *retval = (pg_uuid_t *) palloc0(sizeof(pg_uuid_t)); + const unsigned char * sqlite_blob = sqlite3_value_blob(val); - sqlite_blob = sqlite3_value_blob(val); memcpy(retval->data, sqlite_blob, UUID_LEN); return (struct NullableDatum){UUIDPGetDatum(retval), false}; break; } } - /* - * SQLite UUID output always normalized to blob. - * In sqlite_data_norm.c there is special additional C function. - */ case SQLITE3_TEXT: { if (value_byte_size_blob_or_utf8) @@ -750,7 +754,7 @@ sqlite_bind_sql_var(Form_pg_attribute att, int attnum, Datum value, sqlite3_stmt Oid type = att->atttypid; int32 pgtypmod = att->atttypmod; attnum++; - elog(DEBUG2, "sqlite_fdw : %s %d type=%u relid=%u typmod=%d ", __func__, attnum, type, relid, pgtypmod); + elog(DEBUG2, "sqlite_fdw : %s %d type=%u typmod=%d", __func__, attnum, type, pgtypmod); if (*isnull) {