*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.168 2010/01/02 16:57:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.169 2010/01/02 17:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int i;
bool conflict;
bool found_self;
+ ExprContext *econtext;
TupleTableSlot *existing_slot;
+ TupleTableSlot *save_scantuple;
/*
* If any of the input values are NULL, the constraint check is assumed
values[i]);
}
- /* Need a TupleTableSlot to put existing tuples in */
+ /*
+ * Need a TupleTableSlot to put existing tuples in.
+ *
+ * To use FormIndexDatum, we have to make the econtext's scantuple point
+ * to this slot. Be sure to save and restore caller's value for
+ * scantuple.
+ */
existing_slot = MakeSingleTupleTableSlot(RelationGetDescr(heap));
+ econtext = GetPerTupleExprContext(estate);
+ save_scantuple = econtext->ecxt_scantuple;
+ econtext->ecxt_scantuple = existing_slot;
+
/*
* May have to restart scan from this point if a potential
* conflict is found.
RelationGetRelationName(index)),
errhint("This may be because of a non-immutable index expression.")));
+ econtext->ecxt_scantuple = save_scantuple;
+
ExecDropSingleTupleTableSlot(existing_slot);
return !conflict;
c1 CIRCLE,
c2 TEXT,
EXCLUDE USING gist
- (c1 WITH &&, (c2::circle) WITH ~=)
+ (c1 WITH &&, (c2::circle) WITH &&)
WHERE (circle_center(c1) <> '(0,0)')
);
-- these should succeed because they don't match the index predicate
INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>');
-INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>');
+INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 4>');
-- succeed
INSERT INTO circles VALUES('<(10,10), 10>', '<(0,0), 5>');
-- fail, overlaps
-INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 5>');
+INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>');
-- succeed because c1 doesn't overlap
INSERT INTO circles VALUES('<(20,20), 1>', '<(0,0), 5>');
--- succeed because c2 is not the same
-INSERT INTO circles VALUES('<(20,20), 10>', '<(1,1), 5>');
+-- succeed because c2 doesn't overlap
+INSERT INTO circles VALUES('<(20,20), 10>', '<(10,10), 5>');
-- should fail on existing data without the WHERE clause
ALTER TABLE circles ADD EXCLUDE USING gist
- (c1 WITH &&, (c2::circle) WITH ~=);
+ (c1 WITH &&, (c2::circle) WITH &&);
DROP TABLE circles;
c1 CIRCLE,
c2 TEXT,
EXCLUDE USING gist
- (c1 WITH &&, (c2::circle) WITH ~=)
+ (c1 WITH &&, (c2::circle) WITH &&)
WHERE (circle_center(c1) <> '(0,0)')
);
NOTICE: CREATE TABLE / EXCLUDE will create implicit index "circles_c1_c2_exclusion" for table "circles"
-- these should succeed because they don't match the index predicate
INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>');
-INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>');
+INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 4>');
-- succeed
INSERT INTO circles VALUES('<(10,10), 10>', '<(0,0), 5>');
-- fail, overlaps
-INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 5>');
+INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>');
ERROR: conflicting key value violates exclusion constraint "circles_c1_c2_exclusion"
-DETAIL: Key (c1, (c2::circle))=(<(20,20),10>, <(0,0),5>) conflicts with existing key (c1, (c2::circle))=(<(10,10),10>, <(0,0),5>).
+DETAIL: Key (c1, (c2::circle))=(<(20,20),10>, <(0,0),4>) conflicts with existing key (c1, (c2::circle))=(<(10,10),10>, <(0,0),5>).
-- succeed because c1 doesn't overlap
INSERT INTO circles VALUES('<(20,20), 1>', '<(0,0), 5>');
--- succeed because c2 is not the same
-INSERT INTO circles VALUES('<(20,20), 10>', '<(1,1), 5>');
+-- succeed because c2 doesn't overlap
+INSERT INTO circles VALUES('<(20,20), 10>', '<(10,10), 5>');
-- should fail on existing data without the WHERE clause
ALTER TABLE circles ADD EXCLUDE USING gist
- (c1 WITH &&, (c2::circle) WITH ~=);
+ (c1 WITH &&, (c2::circle) WITH &&);
NOTICE: ALTER TABLE / ADD EXCLUDE will create implicit index "circles_c1_c2_exclusion1" for table "circles"
ERROR: could not create exclusion constraint "circles_c1_c2_exclusion1"
-DETAIL: Key (c1, (c2::circle))=(<(0,0),5>, <(0,0),5>) conflicts with key (c1, (c2::circle))=(<(0,0),5>, <(0,0),5>).
+DETAIL: Key (c1, (c2::circle))=(<(0,0),5>, <(0,0),5>) conflicts with key (c1, (c2::circle))=(<(0,0),5>, <(0,0),4>).
DROP TABLE circles;
-- Check deferred exclusion constraint
CREATE TABLE deferred_excl (