33
33
#include "nodes/makefuncs.h"
34
34
#include "nodes/parsenodes.h"
35
35
36
+ #include "optimizer/planner.h"
37
+
36
38
#include "replication/origin.h"
37
39
40
+ #include "rewrite/rewriteHandler.h"
41
+
38
42
#include "storage/ipc.h"
39
43
#include "storage/lmgr.h"
40
44
#include "storage/proc.h"
@@ -229,11 +233,22 @@ create_estate_for_relation(Relation rel)
229
233
{
230
234
EState * estate ;
231
235
ResultRelInfo * resultRelInfo ;
236
+ RangeTblEntry * rte ;
232
237
233
238
estate = CreateExecutorState ();
234
239
240
+ rte = makeNode (RangeTblEntry );
241
+ rte -> rtekind = RTE_RELATION ;
242
+ rte -> relid = RelationGetRelid (rel );
243
+ rte -> relkind = rel -> rd_rel -> relkind ;
244
+ estate -> es_range_table = list_make1 (rte );
245
+
235
246
resultRelInfo = makeNode (ResultRelInfo );
236
- resultRelInfo -> ri_RangeTableIndex = 1 ; /* dummy */
247
+ /* InitResultRelInfo(resultRelInfo,
248
+ rel,
249
+ 1,
250
+ 0);*/
251
+ resultRelInfo -> ri_RangeTableIndex = 1 ;
237
252
resultRelInfo -> ri_RelationDesc = rel ;
238
253
resultRelInfo -> ri_TrigInstrument = NULL ;
239
254
@@ -272,6 +287,69 @@ UserTableUpdateOpenIndexes(EState *estate, TupleTableSlot *slot)
272
287
}
273
288
}
274
289
290
+ static bool
291
+ physatt_in_attmap (PGLogicalRelation * rel , int attid )
292
+ {
293
+ AttrNumber i ;
294
+
295
+ for (i = 0 ; i < rel -> natts ; i ++ )
296
+ if (rel -> attmap [i ] == attid )
297
+ return true;
298
+
299
+ return false;
300
+ }
301
+
302
+ /*
303
+ * Executes default values for columns for which we didn't get any data.
304
+ *
305
+ * TODO: this needs caching, it's not exactly fast.
306
+ */
307
+ static void
308
+ fill_tuple_defaults (PGLogicalRelation * rel , ExprContext * econtext ,
309
+ PGLogicalTupleData * tuple )
310
+ {
311
+ TupleDesc desc = RelationGetDescr (rel -> rel );
312
+ AttrNumber num_phys_attrs = desc -> natts ;
313
+ int i ;
314
+ AttrNumber attnum ,
315
+ num_defaults = 0 ;
316
+ int * defmap ;
317
+ ExprState * * defexprs ;
318
+
319
+ defmap = (int * ) palloc (num_phys_attrs * sizeof (int ));
320
+ defexprs = (ExprState * * ) palloc (num_phys_attrs * sizeof (ExprState * ));
321
+
322
+ for (attnum = 0 ; attnum < num_phys_attrs ; attnum ++ )
323
+ {
324
+ Expr * defexpr ;
325
+
326
+ if (desc -> attrs [attnum ]-> attisdropped )
327
+ continue ;
328
+
329
+ if (physatt_in_attmap (rel , attnum ))
330
+ continue ;
331
+
332
+ defexpr = (Expr * ) build_column_default (rel -> rel , attnum + 1 );
333
+
334
+ if (defexpr != NULL )
335
+ {
336
+ /* Run the expression through planner */
337
+ defexpr = expression_planner (defexpr );
338
+
339
+ /* Initialize executable expression in copycontext */
340
+ defexprs [num_defaults ] = ExecInitExpr (defexpr , NULL );
341
+ defmap [num_defaults ] = attnum ;
342
+ num_defaults ++ ;
343
+ }
344
+
345
+ }
346
+
347
+ for (i = 0 ; i < num_defaults ; i ++ )
348
+ tuple -> values [defmap [i ]] = ExecEvalExpr (defexprs [i ],
349
+ econtext ,
350
+ & tuple -> nulls [defmap [i ]],
351
+ NULL );
352
+ }
275
353
276
354
static void
277
355
handle_insert (StringInfo s )
@@ -298,6 +376,7 @@ handle_insert(StringInfo s)
298
376
299
377
/* Initialize the executor state. */
300
378
estate = create_estate_for_relation (rel -> rel );
379
+ fill_tuple_defaults (rel , GetPerTupleExprContext (estate ), & newtup );
301
380
localslot = ExecInitExtraTupleSlot (estate );
302
381
applyslot = ExecInitExtraTupleSlot (estate );
303
382
ExecSetSlotDescriptor (localslot , RelationGetDescr (rel -> rel ));
@@ -328,6 +407,11 @@ handle_insert(StringInfo s)
328
407
if (apply )
329
408
{
330
409
ExecStoreTuple (applytuple , applyslot , InvalidBuffer , true);
410
+ /* Check the constraints of the tuple */
411
+ if (rel -> rel -> rd_att -> constr )
412
+ ExecConstraints (estate -> es_result_relation_info , applyslot ,
413
+ estate );
414
+
331
415
simple_heap_update (rel -> rel , & localslot -> tts_tuple -> t_self ,
332
416
applytuple );
333
417
/* TODO: check for HOT update? */
@@ -338,6 +422,11 @@ handle_insert(StringInfo s)
338
422
{
339
423
/* No conflict, insert the tuple. */
340
424
ExecStoreTuple (remotetuple , applyslot , InvalidBuffer , true);
425
+ /* Check the constraints of the tuple */
426
+ if (rel -> rel -> rd_att -> constr )
427
+ ExecConstraints (estate -> es_result_relation_info , applyslot ,
428
+ estate );
429
+
341
430
simple_heap_insert (rel -> rel , remotetuple );
342
431
UserTableUpdateOpenIndexes (estate , applyslot );
343
432
}
@@ -414,6 +503,7 @@ handle_update(StringInfo s)
414
503
415
504
/* Initialize the executor state. */
416
505
estate = create_estate_for_relation (rel -> rel );
506
+ fill_tuple_defaults (rel , GetPerTupleExprContext (estate ), & newtup );
417
507
localslot = ExecInitExtraTupleSlot (estate );
418
508
applyslot = ExecInitExtraTupleSlot (estate );
419
509
ExecSetSlotDescriptor (localslot , RelationGetDescr (rel -> rel ));
@@ -469,6 +559,11 @@ handle_update(StringInfo s)
469
559
if (apply )
470
560
{
471
561
ExecStoreTuple (applytuple , applyslot , InvalidBuffer , true);
562
+ /* Check the constraints of the tuple */
563
+ if (rel -> rel -> rd_att -> constr )
564
+ ExecConstraints (estate -> es_result_relation_info , applyslot ,
565
+ estate );
566
+
472
567
simple_heap_update (rel -> rel , & localslot -> tts_tuple -> t_self ,
473
568
applytuple );
474
569
0 commit comments