Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 85ddcf6

Browse files
committed
Add type checking for populate function
1 parent 7ffe6fd commit 85ddcf6

File tree

7 files changed

+54
-11
lines changed

7 files changed

+54
-11
lines changed

deparse.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@
4040
#include "optimizer/clauses.h"
4141
#include "optimizer/prep.h"
4242
#include "optimizer/tlist.h"
43+
#if PG_VERSION_NUM>=120000
44+
#include "optimizer/optimizer.h"
45+
#else
4346
#include "optimizer/var.h"
47+
#endif
4448
#include "parser/parsetree.h"
4549
#include "utils/builtins.h"
4650
#include "utils/lsyscache.h"
@@ -110,7 +114,7 @@ static void deparseExpr(Expr *expr, deparse_expr_cxt *context);
110114
static void deparseVar(Var *node, deparse_expr_cxt *context);
111115
static void deparseConst(Const *node, deparse_expr_cxt *context, int showtype);
112116
static void deparseParam(Param *node, deparse_expr_cxt *context);
113-
static void deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context);
117+
static void deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context);
114118
static void deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context);
115119
static void deparseOpExpr(OpExpr *node, deparse_expr_cxt *context);
116120
static void deparseOperatorName(StringInfo buf, Form_pg_operator opform);
@@ -242,9 +246,9 @@ foreign_expr_walker(Node *node,
242246
case T_Const:
243247
case T_Param:
244248
break;
245-
case T_ArrayRef:
249+
case T_SubscriptingRef:
246250
{
247-
ArrayRef *ar = (ArrayRef *) node;
251+
SubscriptingRef *ar = (SubscriptingRef *) node;
248252

249253
/* Assignment should not be in restrictions. */
250254
if (ar->refassgnexpr != NULL)
@@ -1486,8 +1490,8 @@ deparseExpr(Expr *node, deparse_expr_cxt *context)
14861490
case T_Param:
14871491
deparseParam((Param *) node, context);
14881492
break;
1489-
case T_ArrayRef:
1490-
deparseArrayRef((ArrayRef *) node, context);
1493+
case T_SubscriptingRef:
1494+
deparseSubscriptingRef((SubscriptingRef *) node, context);
14911495
break;
14921496
case T_FuncExpr:
14931497
deparseFuncExpr((FuncExpr *) node, context);
@@ -1721,7 +1725,7 @@ deparseParam(Param *node, deparse_expr_cxt *context)
17211725
* Deparse an array subscript expression.
17221726
*/
17231727
static void
1724-
deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context)
1728+
deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context)
17251729
{
17261730
StringInfo buf = context->buf;
17271731
ListCell *lowlist_item;

expected/test.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
create extension vops;
2+
set extra_float_digits=0;
23
create table s(x real);
34
create table v(x vops_float4);
45
insert into s values(1.0),(2.0),(null),(3.0),(null),(4.0);

sql/test.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
create extension vops;
2+
set extra_float_digits=0;
23
create table s(x real);
34
create table v(x vops_float4);
45
insert into s values(1.0),(2.0),(null),(3.0),(null),(4.0);

vops.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
#include "tcop/utility.h"
2727

2828
#include "utils/array.h"
29-
#include "utils/tqual.h"
3029
#include "utils/datum.h"
3130
#if PG_VERSION_NUM>=120000
31+
#include "access/heapam.h"
3232
#include "utils/float.h"
33+
#else
34+
#include "utils/tqual.h"
3335
#endif
3436
#include "utils/builtins.h"
3537
#include "utils/datetime.h"
@@ -1137,9 +1139,10 @@ UserTableUpdateOpenIndexes()
11371139
if (estate->es_result_relation_info->ri_NumIndices > 0)
11381140
{
11391141
recheckIndexes = ExecInsertIndexTuples(slot,
1142+
#if PG_VERSION_NUM<120000
11401143
&tuple->t_self,
1144+
#endif
11411145
estate, false, NULL, NIL);
1142-
11431146
if (recheckIndexes != NIL)
11441147
ereport(ERROR,
11451148
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1182,7 +1185,7 @@ static void insert_tuple(Datum* values, bool* nulls)
11821185
HeapTuple tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
11831186
#if PG_VERSION_NUM>=120000
11841187
ExecStoreHeapTuple(tup, slot, true);
1185-
simple_heap_insert(rel, ExecFetchSlotHeapTuple(slot, true, NULL));
1188+
simple_table_insert(rel, slot);
11861189
#else
11871190
ExecStoreTuple(tup, slot, InvalidBuffer, true);
11881191
simple_heap_insert(rel, slot->tts_tuple);
@@ -2224,6 +2227,7 @@ Datum vops_populate(PG_FUNCTION_ARGS)
22242227
int rc;
22252228
bool is_null;
22262229
int64 loaded;
2230+
bool type_checked = false;
22272231
static Oid self_oid = InvalidOid;
22282232
char stmt[MAX_SQL_STMT_LEN];
22292233

@@ -2257,6 +2261,7 @@ Datum vops_populate(PG_FUNCTION_ARGS)
22572261
HeapTuple spi_tuple = SPI_tuptable->vals[i];
22582262
char const* name = SPI_getvalue(spi_tuple, spi_tupdesc, 1);
22592263
Oid type_id = DatumGetObjectId(SPI_getbinval(spi_tuple, spi_tupdesc, 2, &is_null));
2264+
types[i].dst_type = type_id;
22602265
types[i].tid = vops_get_type(type_id);
22612266
get_typlenbyvalalign(type_id, &types[i].len, &types[i].byval, &types[i].align);
22622267
if (types[i].tid != VOPS_LAST && types[i].len < 0) { /* varying length type: extract size from atttypmod */
@@ -2294,6 +2299,26 @@ Datum vops_populate(PG_FUNCTION_ARGS)
22942299
if (SPI_processed) {
22952300
HeapTuple spi_tuple = SPI_tuptable->vals[0];
22962301
spi_tupdesc = SPI_tuptable->tupdesc;
2302+
if (!type_checked)
2303+
{
2304+
for (i = 0; i < n_attrs; i++)
2305+
{
2306+
Oid dst_type = types[i].dst_type;
2307+
Oid src_type = SPI_gettypeid(spi_tupdesc, i+1);
2308+
types[i].src_type = src_type;
2309+
if (types[i].tid != VOPS_LAST)
2310+
dst_type = vops_map_tid[types[i].tid];
2311+
if (!(dst_type == src_type ||
2312+
(dst_type == CHAROID && src_type == TEXTOID) ||
2313+
(dst_type == TEXTOID && src_type == VARCHAROID) ||
2314+
(dst_type == TEXTOID && src_type == BPCHAROID)))
2315+
{
2316+
elog(ERROR, "Incompatible type of attribute %d: %s vs. %s",
2317+
i+1, format_type_be(dst_type), format_type_be(src_type));
2318+
}
2319+
}
2320+
type_checked = true;
2321+
}
22972322
if (j == TILE_SIZE) {
22982323
for (i = 0; i < n_attrs; i++) {
22992324
if (types[i].tid != VOPS_LAST) {
@@ -2343,7 +2368,7 @@ Datum vops_populate(PG_FUNCTION_ARGS)
23432368
((vops_bool*)tile)->payload |= (uint64)DatumGetBool(val) << j;
23442369
break;
23452370
case VOPS_CHAR:
2346-
((vops_char*)tile)->payload[j] = SPI_gettypeid(spi_tupdesc, i+1) == CHAROID
2371+
((vops_char*)tile)->payload[j] = types[i].src_type == CHAROID
23472372
? DatumGetChar(val)
23482373
: *VARDATA(DatumGetTextP(val));
23492374
break;

vops.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ typedef struct {
144144
char align;
145145
FmgrInfo inproc;
146146
Oid inproc_param_oid;
147+
Oid src_type;
148+
Oid dst_type;
147149
} vops_type_info;
148150

149151
typedef struct {

vops_fdw.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@
3636
#include "optimizer/planmain.h"
3737
#include "optimizer/plancat.h"
3838
#include "optimizer/restrictinfo.h"
39+
#if PG_VERSION_NUM>=120000
40+
#include "access/table.h"
41+
#include "nodes/primnodes.h"
42+
#include "optimizer/optimizer.h"
43+
#else
3944
#include "optimizer/var.h"
45+
#endif
4046
#include "optimizer/tlist.h"
4147
#include "parser/parsetree.h"
4248
#include "utils/builtins.h"
@@ -1031,7 +1037,7 @@ estimate_path_cost_size(PlannerInfo *root,
10311037
*-----
10321038
*/
10331039
run_cost = ofpinfo->rel_total_cost - ofpinfo->rel_startup_cost;
1034-
run_cost += aggcosts.finalCost * numGroups;
1040+
run_cost += aggcosts.finalCost.per_tuple * numGroups;
10351041
run_cost += cpu_tuple_cost * numGroups;
10361042
run_cost += ptarget->cost.per_tuple * numGroups;
10371043
}

vops_fdw.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515

1616
#include "foreign/foreign.h"
1717
#include "lib/stringinfo.h"
18+
#if PG_VERSION_NUM>=120000
19+
#include "nodes/pathnodes.h"
20+
#else
1821
#include "nodes/relation.h"
22+
#endif
1923
#include "utils/relcache.h"
2024

2125
#include "libpq-fe.h"

0 commit comments

Comments
 (0)