*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.165 2002/06/20 20:29:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.166 2002/06/25 17:27:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
long numberTuples,
ScanDirection direction,
DestReceiver *destfunc);
-static void ExecRetrieve(TupleTableSlot *slot,
+static void ExecSelect(TupleTableSlot *slot,
DestReceiver *destfunc,
EState *estate);
-static void ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
+static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate);
static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate);
-static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
+static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate);
static TupleTableSlot *EvalPlanQualNext(EState *estate);
static void EndEvalPlanQual(EState *estate);
ExecCheckRTPerms(parseTree->rtable, operation);
/*
- * Search for subplans and APPEND nodes to check their rangetables.
+ * Search for subplans and INSERT nodes to check their rangetables.
*/
ExecCheckPlanPerms(plan, parseTree->rtable, operation);
}
/*
* Get the tuple descriptor describing the type of tuples to return.
* (this is especially important if we are creating a relation with
- * "retrieve into")
+ * "SELECT INTO")
*/
tupType = ExecGetTupType(plan); /* tuple descriptor */
* Retrieves all tuples if numberTuples is 0
*
* result is either a slot containing the last tuple in the case
- * of a RETRIEVE or NULL otherwise.
+ * of a SELECT or NULL otherwise.
*
* Note: the ctid attribute is a 'junk' attribute that is removed before the
* user can see it
slot = ExecStoreTuple(newTuple, /* tuple to store */
junkfilter->jf_resultSlot, /* dest slot */
- InvalidBuffer, /* this tuple has no
- * buffer */
+ InvalidBuffer, /* this tuple has no buffer */
true); /* tuple should be pfreed */
- } /* if (junkfilter... */
+ }
/*
* now that we have a tuple, do the appropriate thing with it..
* either return it to the user, add it to a relation someplace,
* delete it from a relation, or modify some of its attributes.
*/
-
switch (operation)
{
case CMD_SELECT:
- ExecRetrieve(slot, /* slot containing tuple */
- destfunc, /* destination's tuple-receiver
- * obj */
- estate); /* */
+ ExecSelect(slot, /* slot containing tuple */
+ destfunc, /* destination's tuple-receiver obj */
+ estate);
result = slot;
break;
case CMD_INSERT:
- ExecAppend(slot, tupleid, estate);
+ ExecInsert(slot, tupleid, estate);
result = NULL;
break;
break;
case CMD_UPDATE:
- ExecReplace(slot, tupleid, estate);
+ ExecUpdate(slot, tupleid, estate);
result = NULL;
break;
/*
* here, result is either a slot containing a tuple in the case of a
- * RETRIEVE or NULL otherwise.
+ * SELECT or NULL otherwise.
*/
return result;
}
/* ----------------------------------------------------------------
- * ExecRetrieve
+ * ExecSelect
*
- * RETRIEVEs are easy.. we just pass the tuple to the appropriate
+ * SELECTs are easy.. we just pass the tuple to the appropriate
* print function. The only complexity is when we do a
- * "retrieve into", in which case we insert the tuple into
+ * "SELECT INTO", in which case we insert the tuple into
* the appropriate relation (note: this is a newly created relation
* so we don't need to worry about indices or locks.)
* ----------------------------------------------------------------
*/
static void
-ExecRetrieve(TupleTableSlot *slot,
- DestReceiver *destfunc,
- EState *estate)
+ExecSelect(TupleTableSlot *slot,
+ DestReceiver *destfunc,
+ EState *estate)
{
HeapTuple tuple;
TupleDesc attrtype;
}
/* ----------------------------------------------------------------
- * ExecAppend
+ * ExecInsert
*
- * APPENDs are trickier.. we have to insert the tuple into
+ * INSERTs are trickier.. we have to insert the tuple into
* the base relation and insert appropriate tuples into the
* index relations.
* ----------------------------------------------------------------
*/
-
static void
-ExecAppend(TupleTableSlot *slot,
+ExecInsert(TupleTableSlot *slot,
ItemPointer tupleid,
EState *estate)
{
* Check the constraints of the tuple
*/
if (resultRelationDesc->rd_att->constr)
- ExecConstraints("ExecAppend", resultRelInfo, slot, estate);
+ ExecConstraints("ExecInsert", resultRelInfo, slot, estate);
/*
* insert the tuple
/* ----------------------------------------------------------------
* ExecDelete
*
- * DELETE is like append, we delete the tuple and its
+ * DELETE is like UPDATE, we delete the tuple and its
* index tuples.
* ----------------------------------------------------------------
*/
}
/* ----------------------------------------------------------------
- * ExecReplace
+ * ExecUpdate
*
- * note: we can't run replace queries with transactions
- * off because replaces are actually appends and our
- * scan will mistakenly loop forever, replacing the tuple
- * it just appended.. This should be fixed but until it
+ * note: we can't run UPDATE queries with transactions
+ * off because UPDATEs are actually INSERTs and our
+ * scan will mistakenly loop forever, updating the tuple
+ * it just inserted.. This should be fixed but until it
* is, we don't want to get stuck in an infinite loop
* which corrupts your database..
* ----------------------------------------------------------------
*/
static void
-ExecReplace(TupleTableSlot *slot,
+ExecUpdate(TupleTableSlot *slot,
ItemPointer tupleid,
EState *estate)
{
*/
if (IsBootstrapProcessingMode())
{
- elog(WARNING, "ExecReplace: replace can't run without transactions");
+ elog(WARNING, "ExecUpdate: UPDATE can't run without transactions");
return;
}
*/
lreplace:;
if (resultRelationDesc->rd_att->constr)
- ExecConstraints("ExecReplace", resultRelInfo, slot, estate);
+ ExecConstraints("ExecUpdate", resultRelInfo, slot, estate);
/*
* replace the heap tuple
/*
* Note: instead of having to update the old index tuples associated
* with the heap tuple, all we do is form and insert new index tuples.
- * This is because replaces are actually deletes and inserts and index
+ * This is because UPDATEs are actually DELETEs and INSERTs and index
* tuple deletion is done automagically by the vacuum daemon. All we
* do is insert new index tuples. -cim 9/27/89
*/
* process indices
*
* heap_update updates a tuple in the base relation by invalidating it
- * and then appending a new tuple to the relation. As a side effect,
+ * and then inserting a new tuple to the relation. As a side effect,
* the tupleid of the new tuple is placed in the new tuple's t_ctid
* field. So we now insert index tuples using the new tupleid stored
* there.
}
void
-ExecConstraints(char *caller, ResultRelInfo *resultRelInfo,
+ExecConstraints(const char *caller, ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate)
{
Relation rel = resultRelInfo->ri_RelationDesc;
alter table atacc1 add constraint atacc_test1 check (test>3);
-- should fail
insert into atacc1 (test) values (2);
-ERROR: ExecAppend: rejected due to CHECK constraint atacc_test1
+ERROR: ExecInsert: rejected due to CHECK constraint atacc_test1
-- should succeed
insert into atacc1 (test) values (4);
drop table atacc1;
alter table atacc1 add constraint atacc_test1 check (test+test2
-- should fail
insert into atacc1 (test,test2,test3) values (4,4,2);
-ERROR: ExecAppend: rejected due to CHECK constraint atacc_test1
+ERROR: ExecInsert: rejected due to CHECK constraint atacc_test1
-- should succeed
insert into atacc1 (test,test2,test3) values (4,4,5);
drop table atacc1;
alter table atacc1 add check (test2>test);
-- should fail for $2
insert into atacc1 (test2, test) values (3, 4);
-ERROR: ExecAppend: rejected due to CHECK constraint $2
+ERROR: ExecInsert: rejected due to CHECK constraint $2
drop table atacc1;
-- inheritance related tests
create table atacc1 (test int);
alter table atacc2 add constraint foo check (test2>0);
-- fail and then succeed on atacc2
insert into atacc2 (test2) values (-3);
-ERROR: ExecAppend: rejected due to CHECK constraint foo
+ERROR: ExecInsert: rejected due to CHECK constraint foo
insert into atacc2 (test2) values (3);
-- fail and then succeed on atacc3
insert into atacc3 (test2) values (-3);
-ERROR: ExecAppend: rejected due to CHECK constraint foo
+ERROR: ExecInsert: rejected due to CHECK constraint foo
insert into atacc3 (test2) values (3);
drop table atacc3;
drop table atacc2;
alter table only atacc2 add constraint foo check (test2>0);
-- fail and then succeed on atacc2
insert into atacc2 (test2) values (-3);
-ERROR: ExecAppend: rejected due to CHECK constraint foo
+ERROR: ExecInsert: rejected due to CHECK constraint foo
insert into atacc2 (test2) values (3);
-- both succeed on atacc3
insert into atacc3 (test2) values (-3);
insert into atacc1 (test2, test) values (2, 3);
ERROR: Cannot insert a duplicate key into unique index atacc1_pkey
insert into atacc1 (test2, test) values (1, NULL);
-ERROR: ExecAppend: Fail to add null value in not null attribute test
+ERROR: ExecInsert: Fail to add null value in not null attribute test
drop table atacc1;
-- alter table / alter column [set/drop] not null tests
-- try altering system catalogs, should fail
create table child (b varchar(255)) inherits (parent);
alter table parent alter a set not null;
insert into parent values (NULL);
-ERROR: ExecAppend: Fail to add null value in not null attribute a
+ERROR: ExecInsert: Fail to add null value in not null attribute a
insert into child (a, b) values (NULL, 'foo');
-ERROR: ExecAppend: Fail to add null value in not null attribute a
+ERROR: ExecInsert: Fail to add null value in not null attribute a
alter table parent alter a drop not null;
insert into parent values (NULL);
insert into child (a, b) values (NULL, 'foo');
delete from parent;
alter table only parent alter a set not null;
insert into parent values (NULL);
-ERROR: ExecAppend: Fail to add null value in not null attribute a
+ERROR: ExecInsert: Fail to add null value in not null attribute a
alter table child alter a set not null;
insert into child (a, b) values (NULL, 'foo');
-ERROR: ExecAppend: Fail to add null value in not null attribute a
+ERROR: ExecInsert: Fail to add null value in not null attribute a
delete from child;
alter table child alter a set not null;
insert into child (a, b) values (NULL, 'foo');
-ERROR: ExecAppend: Fail to add null value in not null attribute a
+ERROR: ExecInsert: Fail to add null value in not null attribute a
drop table child;
drop table parent;
-- test setting and removing default values
INSERT INTO serialTest VALUES ('bar');
INSERT INTO serialTest VALUES ('force', 100);
INSERT INTO serialTest VALUES ('wrong', NULL);
-ERROR: ExecAppend: Fail to add null value in not null attribute f2
+ERROR: ExecInsert: Fail to add null value in not null attribute f2
SELECT * FROM serialTest;
f1 | f2
-------+-----
force | 100
(3 rows)
+CREATE SEQUENCE sequence_test;
+BEGIN;
+SELECT nextval('sequence_test');
+ nextval
+---------
+ 1
+(1 row)
+
+DROP SEQUENCE sequence_test;
+END;
, col4 dnull
);
INSERT INTO nulltest DEFAULT VALUES;
-ERROR: ExecAppend: Fail to add null value in not null attribute col1
+ERROR: ExecInsert: Fail to add null value in not null attribute col1
INSERT INTO nulltest values ('a', 'b', 'c', 'd'); -- Good
INSERT INTO nulltest values (NULL, 'b', 'c', 'd');
-ERROR: ExecAppend: Fail to add null value in not null attribute col1
+ERROR: ExecInsert: Fail to add null value in not null attribute col1
INSERT INTO nulltest values ('a', NULL, 'c', 'd');
-ERROR: ExecAppend: Fail to add null value in not null attribute col2
+ERROR: ExecInsert: Fail to add null value in not null attribute col2
INSERT INTO nulltest values ('a', 'b', NULL, 'd');
-ERROR: ExecAppend: Fail to add null value in not null attribute col3
+ERROR: ExecInsert: Fail to add null value in not null attribute col3
INSERT INTO nulltest values ('a', 'b', 'c', NULL); -- Good
select * from nulltest;
col1 | col2 | col3 | col4
--
create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing');
insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT);
-ERROR: ExecAppend: Fail to add null value in not null attribute col2
+ERROR: ExecInsert: Fail to add null value in not null attribute col2
insert into inserttest (col2, col3) values (3, DEFAULT);
insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT);
insert into inserttest values (DEFAULT, 5, 'test');
3 | bbbb
(2 rows)
+-- HAVING is equivalent to WHERE in this case
+SELECT b, c FROM test_having
+ GROUP BY b, c HAVING b = 3;
+ b | c
+---+----------
+ 3 | BBBB
+ 3 | bbbb
+(2 rows)
+
SELECT lower(c), count(c) FROM test_having
GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a);
lower | count
INSERT INTO CHECK_TBL VALUES (5);
INSERT INTO CHECK_TBL VALUES (4);
INSERT INTO CHECK_TBL VALUES (3);
-ERROR: ExecAppend: rejected due to CHECK constraint check_con
+ERROR: ExecInsert: rejected due to CHECK constraint check_con
INSERT INTO CHECK_TBL VALUES (2);
-ERROR: ExecAppend: rejected due to CHECK constraint check_con
+ERROR: ExecInsert: rejected due to CHECK constraint check_con
INSERT INTO CHECK_TBL VALUES (6);
INSERT INTO CHECK_TBL VALUES (1);
-ERROR: ExecAppend: rejected due to CHECK constraint check_con
+ERROR: ExecInsert: rejected due to CHECK constraint check_con
SELECT '' AS three, * FROM CHECK_TBL;
three | x
-------+---
CHECK (x > 3 and y <> 'check failed' and z < 8));
INSERT INTO CHECK2_TBL VALUES (4, 'check ok', -2);
INSERT INTO CHECK2_TBL VALUES (1, 'x check failed', -2);
-ERROR: ExecAppend: rejected due to CHECK constraint sequence_con
+ERROR: ExecInsert: rejected due to CHECK constraint sequence_con
INSERT INTO CHECK2_TBL VALUES (5, 'z check failed', 10);
-ERROR: ExecAppend: rejected due to CHECK constraint sequence_con
+ERROR: ExecInsert: rejected due to CHECK constraint sequence_con
INSERT INTO CHECK2_TBL VALUES (0, 'check failed', -2);
-ERROR: ExecAppend: rejected due to CHECK constraint sequence_con
+ERROR: ExecInsert: rejected due to CHECK constraint sequence_con
INSERT INTO CHECK2_TBL VALUES (6, 'check failed', 11);
-ERROR: ExecAppend: rejected due to CHECK constraint sequence_con
+ERROR: ExecInsert: rejected due to CHECK constraint sequence_con
INSERT INTO CHECK2_TBL VALUES (7, 'check ok', 7);
SELECT '' AS two, * from CHECK2_TBL;
two | x | y | z
CONSTRAINT INSERT_CON CHECK (x >= 3 AND y <> 'check failed' AND x < 8),
CHECK (x + z = 0));
INSERT INTO INSERT_TBL(x,z) VALUES (2, -2);
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
SELECT '' AS zero, * FROM INSERT_TBL;
zero | x | y | z
------+---+---+---
(1 row)
INSERT INTO INSERT_TBL(y) VALUES ('Y');
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
INSERT INTO INSERT_TBL(y) VALUES ('Y');
INSERT INTO INSERT_TBL(x,z) VALUES (1, -2);
-ERROR: ExecAppend: rejected due to CHECK constraint $2
+ERROR: ExecInsert: rejected due to CHECK constraint $2
INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7);
INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5);
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7);
INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
SELECT '' AS four, * FROM INSERT_TBL;
(4 rows)
INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4);
-ERROR: ExecAppend: rejected due to CHECK constraint $2
+ERROR: ExecInsert: rejected due to CHECK constraint $2
INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed');
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed');
INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
SELECT '' AS six, * FROM INSERT_TBL;
(1 row)
INSERT INTO INSERT_TBL(y) VALUES ('Y');
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
SELECT 'eight' AS one, currval('insert_seq');
one | currval
-------+---------
INHERITS (INSERT_TBL);
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11);
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6);
-ERROR: ExecAppend: rejected due to CHECK constraint insert_child_cy
+ERROR: ExecInsert: rejected due to CHECK constraint insert_child_cy
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7);
-ERROR: ExecAppend: rejected due to CHECK constraint $1
+ERROR: ExecInsert: rejected due to CHECK constraint $1
INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7);
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
SELECT * FROM INSERT_CHILD;
x | y | z | cx | cy
---+--------+----+----+----
INSERT INTO INSERT_TBL SELECT * FROM tmp WHERE yd = 'try again';
INSERT INTO INSERT_TBL(y,z) SELECT yd, -7 FROM tmp WHERE yd = 'try again';
INSERT INTO INSERT_TBL(y,z) SELECT yd, -8 FROM tmp WHERE yd = 'try again';
-ERROR: ExecAppend: rejected due to CHECK constraint insert_con
+ERROR: ExecInsert: rejected due to CHECK constraint insert_con
SELECT '' AS four, * FROM INSERT_TBL;
four | x | y | z
------+---+---------------+----
UPDATE INSERT_TBL SET x = 6 WHERE x = 6;
UPDATE INSERT_TBL SET x = -z, z = -x;
UPDATE INSERT_TBL SET x = z, z = x;
-ERROR: ExecReplace: rejected due to CHECK constraint insert_con
+ERROR: ExecUpdate: rejected due to CHECK constraint insert_con
SELECT * FROM INSERT_TBL;
x | y | z
---+---------------+----
INSERT INTO PRIMARY_TBL VALUES (4, 'three');
INSERT INTO PRIMARY_TBL VALUES (5, 'one');
INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR: ExecAppend: Fail to add null value in not null attribute i
+ERROR: ExecInsert: Fail to add null value in not null attribute i
SELECT '' AS four, * FROM PRIMARY_TBL;
four | i | t
------+---+-------
INSERT INTO PRIMARY_TBL VALUES (4, 'three');
INSERT INTO PRIMARY_TBL VALUES (5, 'one');
INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR: ExecAppend: Fail to add null value in not null attribute i
+ERROR: ExecInsert: Fail to add null value in not null attribute i
SELECT '' AS three, * FROM PRIMARY_TBL;
three | i | t
-------+---+-------
INSERT INTO serialTest VALUES ('wrong', NULL);
SELECT * FROM serialTest;
+
+CREATE SEQUENCE sequence_test;
+
+BEGIN;
+SELECT nextval('sequence_test');
+DROP SEQUENCE sequence_test;
+END;
SELECT b, c FROM test_having
GROUP BY b, c HAVING count(*) = 1;
+-- HAVING is equivalent to WHERE in this case
+SELECT b, c FROM test_having
+ GROUP BY b, c HAVING b = 3;
+
SELECT lower(c), count(c) FROM test_having
GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a);