提交 f93b6974 编写于 作者: B Bruce Momjian

Here's a combination of all the patches I'm currently waiting

    for against a just updated CVS tree. It contains

        Partial new rewrite system that handles subselects,  view
        aggregate  columns, insert into select from view, updates
        with set col = view-value and select rules restriction to
        view definition.

        Updates  for  rule/view  backparsing utility functions to
        handle subselects correct.


        New system views pg_tables and pg_indexes (where you  can
        see the complete index definition in the latter one).

        Enabling array references on query parameters.

        Bugfix for functional index.

        Little changes to system views pg_rules and pg_views.


    The rule system isn't a release-stopper any longer.

    But  another  stopper  is  that  I  don't  know if the latest
    changes to PL/pgSQL (not already in CVS) made it  compile  on
    AIX. Still wait for some response from Dave.

Jan
上级 9b21a18c
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.27 1998/09/07 05:35:30 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.28 1998/10/02 16:27:43 momjian Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId
...@@ -362,7 +362,7 @@ GetIndexValue(HeapTuple tuple, ...@@ -362,7 +362,7 @@ GetIndexValue(HeapTuple tuple,
bool *attNull) bool *attNull)
{ {
Datum returnVal; Datum returnVal;
bool isNull; bool isNull = FALSE;
if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid) if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
{ {
...@@ -375,13 +375,15 @@ GetIndexValue(HeapTuple tuple, ...@@ -375,13 +375,15 @@ GetIndexValue(HeapTuple tuple,
attrNums[i], attrNums[i],
hTupDesc, hTupDesc,
attNull); attNull);
if (*attNull)
isNull = TRUE;
} }
returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo), returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo),
FIgetnArgs(fInfo), FIgetnArgs(fInfo),
(char **) attData, (char **) attData,
&isNull); &isNull);
pfree(attData); pfree(attData);
*attNull = FALSE; *attNull = isNull;
} }
else else
returnVal = heap_getattr(tuple, attrNums[attOff], hTupDesc, attNull); returnVal = heap_getattr(tuple, attrNums[attOff], hTupDesc, attNull);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.13 1998/09/01 04:31:30 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.14 1998/10/02 16:27:45 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "utils/builtins.h" #include "utils/builtins.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
static void checkLockPerms(List *locks, Query *parsetree, int rt_index);
/* /*
* ThisLockWasTriggered * ThisLockWasTriggered
...@@ -170,7 +169,7 @@ matchLocks(CmdType event, ...@@ -170,7 +169,7 @@ matchLocks(CmdType event,
} }
static void void
checkLockPerms(List *locks, Query *parsetree, int rt_index) checkLockPerms(List *locks, Query *parsetree, int rt_index)
{ {
Relation ev_rel; Relation ev_rel;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.21 1998/09/01 04:31:32 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.22 1998/10/02 16:27:46 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -199,11 +199,8 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -199,11 +199,8 @@ DefineQueryRewrite(RuleStmt *stmt)
/* ---------- /* ----------
* The current rewrite handler is known to work on relation level * The current rewrite handler is known to work on relation level
* rules only. And for SELECT events, it expects one non-nothing * rules only. And for SELECT events, it expects one non-nothing
* action that is instead. Since we now hand out views and rules * action that is instead and returns exactly a tuple of the
* to regular users, we must deny anything else. * rewritten relation. This restricts SELECT rules to views.
*
* I know that I must write a new rewrite handler from scratch
* for 6.5 so we can remove these checks and allow all the rules.
* *
* Jan * Jan
* ---------- * ----------
...@@ -217,6 +214,9 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -217,6 +214,9 @@ DefineQueryRewrite(RuleStmt *stmt)
else else
eslot_string = NULL; eslot_string = NULL;
/*
* No rule actions that modify OLD or NEW
*/
if (action != NIL) if (action != NIL)
foreach(l, action) foreach(l, action)
{ {
...@@ -233,23 +233,86 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -233,23 +233,86 @@ DefineQueryRewrite(RuleStmt *stmt)
} }
} }
/*
* Rules ON SELECT are restricted to view definitions
*/
if (event_type == CMD_SELECT) if (event_type == CMD_SELECT)
{ {
TargetEntry *tle;
Resdom *resdom;
Form_pg_attribute attr;
char *attname;
int i;
/*
* So there cannot be INSTEAD NOTHING, ...
*/
if (length(action) == 0) if (length(action) == 0)
{ {
elog(NOTICE, "instead nothing rules on select currently not supported"); elog(NOTICE, "instead nothing rules on select currently not supported");
elog(ERROR, " use views instead"); elog(ERROR, " use views instead");
} }
/*
* ... there cannot be multiple actions, ...
*/
if (length(action) > 1) if (length(action) > 1)
elog(ERROR, "multiple action rules on select currently not supported"); elog(ERROR, "multiple action rules on select currently not supported");
/*
* ... the one action must be a SELECT, ...
*/
query = (Query *) lfirst(action); query = (Query *) lfirst(action);
if (!is_instead || query->commandType != CMD_SELECT) if (!is_instead || query->commandType != CMD_SELECT)
elog(ERROR, "only instead-select rules currently supported on select"); elog(ERROR, "only instead-select rules currently supported on select");
if (event_qual != NULL)
elog(ERROR, "event qualifications not supported for rules on select");
/*
* ... the targetlist of the SELECT action must
* exactly match the event relation ...
*/
event_relation = heap_openr(event_obj->relname);
if (event_relation == NULL)
elog(ERROR, "virtual relations not supported yet");
if (event_relation->rd_att->natts != length(query->targetList))
elog(ERROR, "select rules target list must match event relations structure");
for (i = 1; i <= event_relation->rd_att->natts; i++) {
tle = (TargetEntry *)nth(i - 1, query->targetList);
resdom = tle->resdom;
attr = event_relation->rd_att->attrs[i - 1];
attname = nameout(&(attr->attname));
if (strcmp(resdom->resname, attname) != 0)
elog(ERROR, "select rules target entry %d has different column name from %s", i, attname);
if (attr->atttypid != resdom->restype)
elog(ERROR, "select rules target entry %d has different type from attribute %s", i, attname);
if (attr->atttypmod != resdom->restypmod)
elog(ERROR, "select rules target entry %d has different size from attribute %s", i, attname);
}
/*
* ... and final there must not be another ON SELECT
* rule already.
*/
if (event_relation->rd_rules != NULL) {
for (i = 0; i < event_relation->rd_rules->numLocks; i++) {
RewriteRule *rule;
rule = event_relation->rd_rules->rules[i];
if (rule->event == CMD_SELECT)
elog(ERROR, "%s is already a view", nameout(&(event_relation->rd_rel->relname)));
}
}
heap_close(event_relation);
} }
/* /*
* This rule is currently allowed - too restricted I know - but women * This rule is allowed - install it.
* and children first Jan
*/ */
event_relation = heap_openr(event_obj->relname); event_relation = heap_openr(event_obj->relname);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.18 1998/09/11 16:39:59 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.19 1998/10/02 16:27:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -73,6 +73,23 @@ OffsetVarNodes(Node *node, int offset) ...@@ -73,6 +73,23 @@ OffsetVarNodes(Node *node, int offset)
OffsetVarNodes((Node *) expr->args, offset); OffsetVarNodes((Node *) expr->args, offset);
} }
break; break;
case T_Iter:
{
Iter *iter = (Iter *) node;
OffsetVarNodes((Node *) iter->iterexpr, offset);
}
break;
case T_ArrayRef:
{
ArrayRef *ref = (ArrayRef *) node;
OffsetVarNodes((Node *) ref->refupperindexpr, offset);
OffsetVarNodes((Node *) ref->reflowerindexpr, offset);
OffsetVarNodes((Node *) ref->refexpr, offset);
OffsetVarNodes((Node *) ref->refassgnexpr, offset);
}
break;
case T_Var: case T_Var:
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
...@@ -157,6 +174,23 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up) ...@@ -157,6 +174,23 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
ChangeVarNodes((Node *) expr->args, old_varno, new_varno, sublevels_up); ChangeVarNodes((Node *) expr->args, old_varno, new_varno, sublevels_up);
} }
break; break;
case T_Iter:
{
Iter *iter = (Iter *) node;
ChangeVarNodes((Node *) iter->iterexpr, old_varno, new_varno, sublevels_up);
}
break;
case T_ArrayRef:
{
ArrayRef *ref = (ArrayRef *) node;
ChangeVarNodes((Node *) ref->refupperindexpr, old_varno, new_varno, sublevels_up);
ChangeVarNodes((Node *) ref->reflowerindexpr, old_varno, new_varno, sublevels_up);
ChangeVarNodes((Node *) ref->refexpr, old_varno, new_varno, sublevels_up);
ChangeVarNodes((Node *) ref->refassgnexpr, old_varno, new_varno, sublevels_up);
}
break;
case T_Var: case T_Var:
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
...@@ -353,6 +387,20 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr, ...@@ -353,6 +387,20 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)), ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)),
sublevels_up); sublevels_up);
break; break;
case T_Iter:
ResolveNew(info, targetlist, (Node **) (&(((Iter *) node)->iterexpr)),
sublevels_up);
break;
case T_ArrayRef:
ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refupperindexpr)),
sublevels_up);
ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->reflowerindexpr)),
sublevels_up);
ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refexpr)),
sublevels_up);
ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refassgnexpr)),
sublevels_up);
break;
case T_Var: case T_Var:
{ {
int this_varno = (int) ((Var *) node)->varno; int this_varno = (int) ((Var *) node)->varno;
...@@ -454,6 +502,38 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -454,6 +502,38 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
sublevels_up); sublevels_up);
} }
break; break;
case T_Iter:
{
Iter *iter = (Iter *) node;
nodeHandleRIRAttributeRule((Node **) (&(iter->iterexpr)), rtable,
targetlist, rt_index, attr_num,
modified, badsql,
sublevels_up);
}
break;
case T_ArrayRef:
{
ArrayRef *ref = (ArrayRef *) node;
nodeHandleRIRAttributeRule((Node **) (&(ref->refupperindexpr)), rtable,
targetlist, rt_index, attr_num,
modified, badsql,
sublevels_up);
nodeHandleRIRAttributeRule((Node **) (&(ref->reflowerindexpr)), rtable,
targetlist, rt_index, attr_num,
modified, badsql,
sublevels_up);
nodeHandleRIRAttributeRule((Node **) (&(ref->refexpr)), rtable,
targetlist, rt_index, attr_num,
modified, badsql,
sublevels_up);
nodeHandleRIRAttributeRule((Node **) (&(ref->refassgnexpr)), rtable,
targetlist, rt_index, attr_num,
modified, badsql,
sublevels_up);
}
break;
case T_Var: case T_Var:
{ {
int this_varno = ((Var *) node)->varno; int this_varno = ((Var *) node)->varno;
...@@ -598,6 +678,33 @@ nodeHandleViewRule(Node **nodePtr, ...@@ -598,6 +678,33 @@ nodeHandleViewRule(Node **nodePtr,
rt_index, modified, sublevels_up); rt_index, modified, sublevels_up);
} }
break; break;
case T_Iter:
{
Iter *iter = (Iter *) node;
nodeHandleViewRule((Node **) (&(iter->iterexpr)),
rtable, targetlist,
rt_index, modified, sublevels_up);
}
break;
case T_ArrayRef:
{
ArrayRef *ref = (ArrayRef *) node;
nodeHandleViewRule((Node **) (&(ref->refupperindexpr)),
rtable, targetlist,
rt_index, modified, sublevels_up);
nodeHandleViewRule((Node **) (&(ref->reflowerindexpr)),
rtable, targetlist,
rt_index, modified, sublevels_up);
nodeHandleViewRule((Node **) (&(ref->refexpr)),
rtable, targetlist,
rt_index, modified, sublevels_up);
nodeHandleViewRule((Node **) (&(ref->refassgnexpr)),
rtable, targetlist,
rt_index, modified, sublevels_up);
}
break;
case T_Var: case T_Var:
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
......
此差异已折叠。
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
# #
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.55 1998/09/09 18:16:36 momjian Exp $ # $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.56 1998/10/02 16:27:53 momjian Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -435,6 +435,7 @@ echo "REVOKE ALL on pg_shadow FROM public" | \ ...@@ -435,6 +435,7 @@ echo "REVOKE ALL on pg_shadow FROM public" | \
echo "Creating view pg_rules" echo "Creating view pg_rules"
echo "CREATE TABLE xpg_rules ( \ echo "CREATE TABLE xpg_rules ( \
tablename name, \
rulename name, \ rulename name, \
definition text);" | postgres $PGSQL_OPT template1 > /dev/null definition text);" | postgres $PGSQL_OPT template1 > /dev/null
#move it into pg_rules #move it into pg_rules
...@@ -445,12 +446,18 @@ echo "UPDATE pg_type SET typname = 'pg_rules' WHERE typname = 'xpg_rules';" |\ ...@@ -445,12 +446,18 @@ echo "UPDATE pg_type SET typname = 'pg_rules' WHERE typname = 'xpg_rules';" |\
mv $PGDATA/base/template1/xpg_rules $PGDATA/base/template1/pg_rules mv $PGDATA/base/template1/xpg_rules $PGDATA/base/template1/pg_rules
echo "CREATE RULE \"_RETpg_rules\" AS ON SELECT TO pg_rules DO INSTEAD \ echo "CREATE RULE \"_RETpg_rules\" AS ON SELECT TO pg_rules DO INSTEAD \
SELECT rulename, pg_get_ruledef(rulename) AS definition \ SELECT C.relname AS tablename, \
FROM pg_rewrite;" | postgres $PGSQL_OPT template1 > /dev/null R.rulename AS rulename, \
pg_get_ruledef(R.rulename) AS definition \
FROM pg_rewrite R, pg_class C \
WHERE R.rulename !~ '^_RET' \
AND C.oid = R.ev_class;" | \
postgres $PGSQL_OPT template1 > /dev/null
echo "Creating view pg_views" echo "Creating view pg_views"
echo "CREATE TABLE xpg_views ( \ echo "CREATE TABLE xpg_views ( \
viewname name, \ viewname name, \
viewowner name, \
definition text);" | postgres $PGSQL_OPT template1 > /dev/null definition text);" | postgres $PGSQL_OPT template1 > /dev/null
#move it into pg_views #move it into pg_views
echo "UPDATE pg_class SET relname = 'pg_views' WHERE relname = 'xpg_views';" |\ echo "UPDATE pg_class SET relname = 'pg_views' WHERE relname = 'xpg_views';" |\
...@@ -461,11 +468,57 @@ mv $PGDATA/base/template1/xpg_views $PGDATA/base/template1/pg_views ...@@ -461,11 +468,57 @@ mv $PGDATA/base/template1/xpg_views $PGDATA/base/template1/pg_views
echo "CREATE RULE \"_RETpg_views\" AS ON SELECT TO pg_views DO INSTEAD \ echo "CREATE RULE \"_RETpg_views\" AS ON SELECT TO pg_views DO INSTEAD \
SELECT relname AS viewname, \ SELECT relname AS viewname, \
pg_get_userbyid(relowner) AS viewowner, \
pg_get_viewdef(relname) AS definition \ pg_get_viewdef(relname) AS definition \
FROM pg_class WHERE relhasrules AND \ FROM pg_class WHERE relhasrules AND \
pg_get_viewdef(relname) != 'Not a view';" | \ pg_get_viewdef(relname) != 'Not a view';" | \
postgres $PGSQL_OPT template1 > /dev/null postgres $PGSQL_OPT template1 > /dev/null
echo "Creating view pg_tables"
echo "CREATE TABLE xpg_tables ( \
tablename name, \
tableowner name, \
hasindexes bool, \
hasrules bool, \
hastriggers bool);" | postgres $PGSQL_OPT template1 > /dev/null
#move it into pg_tables
echo "UPDATE pg_class SET relname = 'pg_tables' WHERE relname = 'xpg_tables';" |\
postgres $PGSQL_OPT template1 > /dev/null
echo "UPDATE pg_type SET typname = 'pg_tables' WHERE typname = 'xpg_tables';" |\
postgres $PGSQL_OPT template1 > /dev/null
mv $PGDATA/base/template1/xpg_tables $PGDATA/base/template1/pg_tables
echo "CREATE RULE \"_RETpg_tables\" AS ON SELECT TO pg_tables DO INSTEAD \
SELECT relname AS tablename, \
pg_get_userbyid(relowner) AS tableowner, \
relhasindex AS hasindexes, \
relhasrules AS hasrules, \
(reltriggers > 0) AS hastriggers \
FROM pg_class WHERE relkind IN ('r', 's') \
AND pg_get_viewdef(relname) = 'Not a view';" | \
postgres $PGSQL_OPT template1 > /dev/null
echo "Creating view pg_indexes"
echo "CREATE TABLE xpg_indexes ( \
tablename name, \
indexname name, \
indexdef text);" | postgres $PGSQL_OPT template1 > /dev/null
#move it into pg_indexes
echo "UPDATE pg_class SET relname = 'pg_indexes' WHERE relname = 'xpg_indexes';" |\
postgres $PGSQL_OPT template1 > /dev/null
echo "UPDATE pg_type SET typname = 'pg_indexes' WHERE typname = 'xpg_indexes';" |\
postgres $PGSQL_OPT template1 > /dev/null
mv $PGDATA/base/template1/xpg_indexes $PGDATA/base/template1/pg_indexes
echo "CREATE RULE \"_RETpg_indexes\" AS ON SELECT TO pg_indexes DO INSTEAD \
SELECT C.relname AS tablename, \
I.relname AS indexname, \
pg_get_indexdef(X.indexrelid) AS indexdef \
FROM pg_index X, pg_class C, pg_class I \
WHERE C.oid = X.indrelid \
AND I.oid = X.indexrelid;" | \
postgres $PGSQL_OPT template1 > /dev/null
echo "Loading pg_description" echo "Loading pg_description"
echo "copy pg_description from '$TEMPLATE_DESCR'" | \ echo "copy pg_description from '$TEMPLATE_DESCR'" | \
postgres $PGSQL_OPT template1 > /dev/null postgres $PGSQL_OPT template1 > /dev/null
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_proc.h,v 1.69 1998/09/01 04:35:10 momjian Exp $ * $Id: pg_proc.h,v 1.70 1998/10/02 16:27:55 momjian Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
...@@ -2040,6 +2040,10 @@ DATA(insert OID = 1640 ( pg_get_ruledef PGUID 11 f t f 1 f 25 "19" 100 0 0 1 ...@@ -2040,6 +2040,10 @@ DATA(insert OID = 1640 ( pg_get_ruledef PGUID 11 f t f 1 f 25 "19" 100 0 0 1
DESCR("source text of a rule"); DESCR("source text of a rule");
DATA(insert OID = 1641 ( pg_get_viewdef PGUID 11 f t f 1 f 25 "19" 100 0 0 100 foo bar )); DATA(insert OID = 1641 ( pg_get_viewdef PGUID 11 f t f 1 f 25 "19" 100 0 0 100 foo bar ));
DESCR("select statement of a view"); DESCR("select statement of a view");
DATA(insert OID = 1642 ( pg_get_userbyid PGUID 11 f t f 1 f 19 "23" 100 0 0 100 foo bar ));
DESCR("user name by UID (with fallback)");
DATA(insert OID = 1643 ( pg_get_indexdef PGUID 11 f t f 1 f 25 "26" 100 0 0 100 foo bar ));
DESCR("index description");
/* /*
* prototypes for functions pg_proc.c * prototypes for functions pg_proc.c
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: locks.h,v 1.9 1998/09/01 04:37:57 momjian Exp $ * $Id: locks.h,v 1.10 1998/10/02 16:27:58 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,5 +19,6 @@ ...@@ -19,5 +19,6 @@
extern List *matchLocks(CmdType event, RuleLock *rulelocks, int varno, extern List *matchLocks(CmdType event, RuleLock *rulelocks, int varno,
Query *parsetree); Query *parsetree);
extern void checkLockPerms(List *locks, Query *parsetree, int rt_index);
#endif /* LOCKS_H */ #endif /* LOCKS_H */
...@@ -671,3 +671,181 @@ QUERY: select * from rtest_nothn3; ...@@ -671,3 +671,181 @@ QUERY: select * from rtest_nothn3;
200|OK 200|OK
(2 rows) (2 rows)
QUERY: create table rtest_view1 (a int4, b text, v bool);
QUERY: create table rtest_view2 (a int4);
QUERY: create table rtest_view3 (a int4, b text);
QUERY: create table rtest_view4 (a int4, b text, c int4);
QUERY: create view rtest_vview1 as select a, b from rtest_view1 X
where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
QUERY: create view rtest_vview2 as select a, b from rtest_view1 where v;
QUERY: create view rtest_vview3 as select a, b from rtest_vview2 X
where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
QUERY: create view rtest_vview4 as select X.a, X.b, count(Y.a) as refcount
from rtest_view1 X, rtest_view2 Y
where X.a = Y.a
group by X.a, X.b;
QUERY: create function rtest_viewfunc1(int4) returns int4 as
'select count(*) from rtest_view2 where a = $1'
language 'sql';
QUERY: create view rtest_vview5 as select a, b, rtest_viewfunc1(a) as refcount
from rtest_view1;
QUERY: insert into rtest_view1 values (1, 'item 1', 't');
QUERY: insert into rtest_view1 values (2, 'item 2', 't');
QUERY: insert into rtest_view1 values (3, 'item 3', 't');
QUERY: insert into rtest_view1 values (4, 'item 4', 'f');
QUERY: insert into rtest_view1 values (5, 'item 5', 't');
QUERY: insert into rtest_view1 values (6, 'item 6', 'f');
QUERY: insert into rtest_view1 values (7, 'item 7', 't');
QUERY: insert into rtest_view1 values (8, 'item 8', 't');
QUERY: insert into rtest_view2 values (2);
QUERY: insert into rtest_view2 values (2);
QUERY: insert into rtest_view2 values (4);
QUERY: insert into rtest_view2 values (5);
QUERY: insert into rtest_view2 values (7);
QUERY: insert into rtest_view2 values (7);
QUERY: insert into rtest_view2 values (7);
QUERY: insert into rtest_view2 values (7);
QUERY: select * from rtest_vview1;
a|b
-+------
2|item 2
4|item 4
5|item 5
7|item 7
(4 rows)
QUERY: select * from rtest_vview2;
a|b
-+------
1|item 1
2|item 2
3|item 3
5|item 5
7|item 7
8|item 8
(6 rows)
QUERY: select * from rtest_vview3;
a|b
-+------
2|item 2
5|item 5
7|item 7
(3 rows)
QUERY: select * from rtest_vview4;
a|b |refcount
-+------+--------
2|item 2| 2
4|item 4| 1
5|item 5| 1
7|item 7| 4
(4 rows)
QUERY: select * from rtest_vview5;
a|b |refcount
-+------+--------
1|item 1| 0
2|item 2| 2
3|item 3| 0
4|item 4| 1
5|item 5| 1
6|item 6| 0
7|item 7| 4
8|item 8| 0
(8 rows)
QUERY: insert into rtest_view3 select * from rtest_vview1 where a < 7;
QUERY: select * from rtest_view3;
a|b
-+------
2|item 2
4|item 4
5|item 5
(3 rows)
QUERY: delete from rtest_view3;
QUERY: insert into rtest_view3 select * from rtest_vview2 where a != 5 and b !~ '2';
QUERY: select * from rtest_view3;
a|b
-+------
1|item 1
3|item 3
7|item 7
8|item 8
(4 rows)
QUERY: delete from rtest_view3;
QUERY: insert into rtest_view3 select * from rtest_vview3;
QUERY: select * from rtest_view3;
a|b
-+------
2|item 2
5|item 5
7|item 7
(3 rows)
QUERY: delete from rtest_view3;
QUERY: insert into rtest_view4 select * from rtest_vview4 where 3 > refcount;
QUERY: select * from rtest_view4;
a|b |c
-+------+-
2|item 2|2
4|item 4|1
5|item 5|1
(3 rows)
QUERY: delete from rtest_view4;
QUERY: insert into rtest_view4 select * from rtest_vview5 where a > 2 and refcount = 0;
QUERY: select * from rtest_view4;
a|b |c
-+------+-
3|item 3|0
6|item 6|0
8|item 8|0
(3 rows)
QUERY: delete from rtest_view4;
QUERY: create table rtest_comp (
part text,
unit char(4),
size float
);
QUERY: create table rtest_unitfact (
unit char(4),
factor float
);
QUERY: create view rtest_vcomp as
select X.part, (X.size * Y.factor) as size_in_cm
from rtest_comp X, rtest_unitfact Y
where X.unit = Y.unit;
QUERY: insert into rtest_unitfact values ('m', 100.0);
QUERY: insert into rtest_unitfact values ('cm', 1.0);
QUERY: insert into rtest_unitfact values ('inch', 2.54);
QUERY: insert into rtest_comp values ('p1', 'm', 5.0);
QUERY: insert into rtest_comp values ('p2', 'm', 3.0);
QUERY: insert into rtest_comp values ('p3', 'cm', 5.0);
QUERY: insert into rtest_comp values ('p4', 'cm', 15.0);
QUERY: insert into rtest_comp values ('p5', 'inch', 7.0);
QUERY: insert into rtest_comp values ('p6', 'inch', 4.4);
QUERY: select * from rtest_vcomp order by part;
part|size_in_cm
----+----------
p1 | 500
p2 | 300
p3 | 5
p4 | 15
p5 | 17.78
p6 | 11.176
(6 rows)
QUERY: select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using >;
part|size_in_cm
----+----------
p1 | 500
p2 | 300
p5 | 17.78
p4 | 15
p6 | 11.176
(5 rows)
...@@ -404,3 +404,100 @@ insert into rtest_nothn2 select * from rtest_nothn4; ...@@ -404,3 +404,100 @@ insert into rtest_nothn2 select * from rtest_nothn4;
select * from rtest_nothn2; select * from rtest_nothn2;
select * from rtest_nothn3; select * from rtest_nothn3;
create table rtest_view1 (a int4, b text, v bool);
create table rtest_view2 (a int4);
create table rtest_view3 (a int4, b text);
create table rtest_view4 (a int4, b text, c int4);
create view rtest_vview1 as select a, b from rtest_view1 X
where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
create view rtest_vview2 as select a, b from rtest_view1 where v;
create view rtest_vview3 as select a, b from rtest_vview2 X
where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
create view rtest_vview4 as select X.a, X.b, count(Y.a) as refcount
from rtest_view1 X, rtest_view2 Y
where X.a = Y.a
group by X.a, X.b;
create function rtest_viewfunc1(int4) returns int4 as
'select count(*) from rtest_view2 where a = $1'
language 'sql';
create view rtest_vview5 as select a, b, rtest_viewfunc1(a) as refcount
from rtest_view1;
insert into rtest_view1 values (1, 'item 1', 't');
insert into rtest_view1 values (2, 'item 2', 't');
insert into rtest_view1 values (3, 'item 3', 't');
insert into rtest_view1 values (4, 'item 4', 'f');
insert into rtest_view1 values (5, 'item 5', 't');
insert into rtest_view1 values (6, 'item 6', 'f');
insert into rtest_view1 values (7, 'item 7', 't');
insert into rtest_view1 values (8, 'item 8', 't');
insert into rtest_view2 values (2);
insert into rtest_view2 values (2);
insert into rtest_view2 values (4);
insert into rtest_view2 values (5);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
select * from rtest_vview1;
select * from rtest_vview2;
select * from rtest_vview3;
select * from rtest_vview4;
select * from rtest_vview5;
insert into rtest_view3 select * from rtest_vview1 where a < 7;
select * from rtest_view3;
delete from rtest_view3;
insert into rtest_view3 select * from rtest_vview2 where a != 5 and b !~ '2';
select * from rtest_view3;
delete from rtest_view3;
insert into rtest_view3 select * from rtest_vview3;
select * from rtest_view3;
delete from rtest_view3;
insert into rtest_view4 select * from rtest_vview4 where 3 > refcount;
select * from rtest_view4;
delete from rtest_view4;
insert into rtest_view4 select * from rtest_vview5 where a > 2 and refcount = 0;
select * from rtest_view4;
delete from rtest_view4;
--
-- Test for computations in views
--
create table rtest_comp (
part text,
unit char(4),
size float
);
create table rtest_unitfact (
unit char(4),
factor float
);
create view rtest_vcomp as
select X.part, (X.size * Y.factor) as size_in_cm
from rtest_comp X, rtest_unitfact Y
where X.unit = Y.unit;
insert into rtest_unitfact values ('m', 100.0);
insert into rtest_unitfact values ('cm', 1.0);
insert into rtest_unitfact values ('inch', 2.54);
insert into rtest_comp values ('p1', 'm', 5.0);
insert into rtest_comp values ('p2', 'm', 3.0);
insert into rtest_comp values ('p3', 'cm', 5.0);
insert into rtest_comp values ('p4', 'cm', 15.0);
insert into rtest_comp values ('p5', 'inch', 7.0);
insert into rtest_comp values ('p6', 'inch', 4.4);
select * from rtest_vcomp order by part;
select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using >;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册