Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit116d2bb

Browse files
committed
Add IS UNKNOWN, IS NOT UNKNOWN boolean tests, fix the existing boolean
tests to return the correct results per SQL9x when given NULL inputs.Reimplement these tests as well as IS [NOT] NULL to have their ownexpression node types, instead of depending on special functions.From Joe Conway, with a little help from Tom Lane.
1 parent8c30aca commit116d2bb

File tree

18 files changed

+662
-149
lines changed

18 files changed

+662
-149
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.61 2001/06/15 21:03:07 tgl Exp $ -->
1+
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.62 2001/06/19 22:39:08 tgl Exp $ -->
22

33
<chapter id="functions">
44
<title>Functions and Operators</title>
@@ -273,6 +273,21 @@
273273
<productname>Microsoft Access</productname>) to work, but this may
274274
be discontinued in a future release.
275275
</para>
276+
277+
<para>
278+
Boolean values can be tested using the constructs
279+
<synopsis>
280+
<replaceable>expression</replaceable> IS TRUE
281+
<replaceable>expression</replaceable> IS NOT TRUE
282+
<replaceable>expression</replaceable> IS FALSE
283+
<replaceable>expression</replaceable> IS NOT FALSE
284+
<replaceable>expression</replaceable> IS UNKNOWN
285+
<replaceable>expression</replaceable> IS NOT UNKNOWN
286+
</synopsis>
287+
These are similar to <literal>IS NULL</literal> in that they will
288+
always return TRUE or FALSE, never NULL, even when the operand is NULL.
289+
A NULL input is treated as the logical value UNKNOWN.
290+
</para>
276291
</sect1>
277292

278293

‎doc/src/sgml/syntax.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.42 2001/05/12 22:51:35 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.43 2001/06/19 22:39:08 tgl Exp $
33
-->
44

55
<chapter id="sql-syntax">
@@ -1060,7 +1060,7 @@ SELECT (5 !) - 6;
10601060
<row>
10611061
<entry><token>IS</token></entry>
10621062
<entry></entry>
1063-
<entry>test for TRUE, FALSE, NULL</entry>
1063+
<entry>test for TRUE, FALSE,UNKNOWN,NULL</entry>
10641064
</row>
10651065

10661066
<row>

‎src/backend/executor/execQual.c

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.86 2001/04/1904:29:02 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.87 2001/06/1922:39:11 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -62,6 +62,10 @@ static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
6262
staticDatumExecEvalOr(Expr*orExpr,ExprContext*econtext,bool*isNull);
6363
staticDatumExecEvalCase(CaseExpr*caseExpr,ExprContext*econtext,
6464
bool*isNull,ExprDoneCond*isDone);
65+
staticDatumExecEvalNullTest(NullTest*ntest,ExprContext*econtext,
66+
bool*isNull,ExprDoneCond*isDone);
67+
staticDatumExecEvalBooleanTest(BooleanTest*btest,ExprContext*econtext,
68+
bool*isNull,ExprDoneCond*isDone);
6569

6670

6771
/*----------
@@ -1091,6 +1095,126 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
10911095
return (Datum)0;
10921096
}
10931097

1098+
/* ----------------------------------------------------------------
1099+
*ExecEvalNullTest
1100+
*
1101+
*Evaluate a NullTest node.
1102+
* ----------------------------------------------------------------
1103+
*/
1104+
staticDatum
1105+
ExecEvalNullTest(NullTest*ntest,
1106+
ExprContext*econtext,
1107+
bool*isNull,
1108+
ExprDoneCond*isDone)
1109+
{
1110+
Datumresult;
1111+
1112+
result=ExecEvalExpr(ntest->arg,econtext,isNull,isDone);
1113+
switch (ntest->nulltesttype)
1114+
{
1115+
caseIS_NULL:
1116+
if (*isNull)
1117+
{
1118+
*isNull= false;
1119+
returnBoolGetDatum(true);
1120+
}
1121+
else
1122+
returnBoolGetDatum(false);
1123+
caseIS_NOT_NULL:
1124+
if (*isNull)
1125+
{
1126+
*isNull= false;
1127+
returnBoolGetDatum(false);
1128+
}
1129+
else
1130+
returnBoolGetDatum(true);
1131+
default:
1132+
elog(ERROR,"ExecEvalNullTest: unexpected nulltesttype %d",
1133+
(int)ntest->nulltesttype);
1134+
return (Datum)0;/* keep compiler quiet */
1135+
}
1136+
}
1137+
1138+
/* ----------------------------------------------------------------
1139+
*ExecEvalBooleanTest
1140+
*
1141+
*Evaluate a BooleanTest node.
1142+
* ----------------------------------------------------------------
1143+
*/
1144+
staticDatum
1145+
ExecEvalBooleanTest(BooleanTest*btest,
1146+
ExprContext*econtext,
1147+
bool*isNull,
1148+
ExprDoneCond*isDone)
1149+
{
1150+
Datumresult;
1151+
1152+
result=ExecEvalExpr(btest->arg,econtext,isNull,isDone);
1153+
switch (btest->booltesttype)
1154+
{
1155+
caseIS_TRUE:
1156+
if (*isNull)
1157+
{
1158+
*isNull= false;
1159+
returnBoolGetDatum(false);
1160+
}
1161+
elseif (DatumGetBool(result))
1162+
returnBoolGetDatum(true);
1163+
else
1164+
returnBoolGetDatum(false);
1165+
caseIS_NOT_TRUE:
1166+
if (*isNull)
1167+
{
1168+
*isNull= false;
1169+
returnBoolGetDatum(true);
1170+
}
1171+
elseif (DatumGetBool(result))
1172+
returnBoolGetDatum(false);
1173+
else
1174+
returnBoolGetDatum(true);
1175+
caseIS_FALSE:
1176+
if (*isNull)
1177+
{
1178+
*isNull= false;
1179+
returnBoolGetDatum(false);
1180+
}
1181+
elseif (DatumGetBool(result))
1182+
returnBoolGetDatum(false);
1183+
else
1184+
returnBoolGetDatum(true);
1185+
caseIS_NOT_FALSE:
1186+
if (*isNull)
1187+
{
1188+
*isNull= false;
1189+
returnBoolGetDatum(true);
1190+
}
1191+
elseif (DatumGetBool(result))
1192+
returnBoolGetDatum(true);
1193+
else
1194+
returnBoolGetDatum(false);
1195+
caseIS_UNKNOWN:
1196+
if (*isNull)
1197+
{
1198+
*isNull= false;
1199+
returnBoolGetDatum(true);
1200+
}
1201+
else
1202+
returnBoolGetDatum(false);
1203+
caseIS_NOT_UNKNOWN:
1204+
if (*isNull)
1205+
{
1206+
*isNull= false;
1207+
returnBoolGetDatum(false);
1208+
}
1209+
else
1210+
returnBoolGetDatum(true);
1211+
default:
1212+
elog(ERROR,"ExecEvalBooleanTest: unexpected booltesttype %d",
1213+
(int)btest->booltesttype);
1214+
return (Datum)0;/* keep compiler quiet */
1215+
}
1216+
}
1217+
10941218
/* ----------------------------------------------------------------
10951219
*ExecEvalFieldSelect
10961220
*
@@ -1266,6 +1390,18 @@ ExecEvalExpr(Node *expression,
12661390
isNull,
12671391
isDone);
12681392
break;
1393+
caseT_NullTest:
1394+
retDatum=ExecEvalNullTest((NullTest*)expression,
1395+
econtext,
1396+
isNull,
1397+
isDone);
1398+
break;
1399+
caseT_BooleanTest:
1400+
retDatum=ExecEvalBooleanTest((BooleanTest*)expression,
1401+
econtext,
1402+
isNull,
1403+
isDone);
1404+
break;
12691405

12701406
default:
12711407
elog(ERROR,"ExecEvalExpr: unknown expression type %d",

‎src/backend/nodes/copyfuncs.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.144 2001/06/09 23:21:54 petere Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.145 2001/06/19 22:39:11 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1017,6 +1017,42 @@ _copyCaseWhen(CaseWhen *from)
10171017
returnnewnode;
10181018
}
10191019

1020+
/* ----------------
1021+
*_copyNullTest
1022+
* ----------------
1023+
*/
1024+
staticNullTest*
1025+
_copyNullTest(NullTest*from)
1026+
{
1027+
NullTest*newnode=makeNode(NullTest);
1028+
1029+
/*
1030+
* copy remainder of node
1031+
*/
1032+
Node_Copy(from,newnode,arg);
1033+
newnode->nulltesttype=from->nulltesttype;
1034+
1035+
returnnewnode;
1036+
}
1037+
1038+
/* ----------------
1039+
*_copyBooleanTest
1040+
* ----------------
1041+
*/
1042+
staticBooleanTest*
1043+
_copyBooleanTest(BooleanTest*from)
1044+
{
1045+
BooleanTest*newnode=makeNode(BooleanTest);
1046+
1047+
/*
1048+
* copy remainder of node
1049+
*/
1050+
Node_Copy(from,newnode,arg);
1051+
newnode->booltesttype=from->booltesttype;
1052+
1053+
returnnewnode;
1054+
}
1055+
10201056
staticArrayRef*
10211057
_copyArrayRef(ArrayRef*from)
10221058
{
@@ -2954,6 +2990,12 @@ copyObject(void *from)
29542990
caseT_CaseWhen:
29552991
retval=_copyCaseWhen(from);
29562992
break;
2993+
caseT_NullTest:
2994+
retval=_copyNullTest(from);
2995+
break;
2996+
caseT_BooleanTest:
2997+
retval=_copyBooleanTest(from);
2998+
break;
29572999
caseT_FkConstraint:
29583000
retval=_copyFkConstraint(from);
29593001
break;

‎src/backend/nodes/equalfuncs.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.92 2001/06/09 23:21:54 petere Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.93 2001/06/19 22:39:11 tgl Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -1712,6 +1712,26 @@ _equalCaseWhen(CaseWhen *a, CaseWhen *b)
17121712
return true;
17131713
}
17141714

1715+
staticbool
1716+
_equalNullTest(NullTest*a,NullTest*b)
1717+
{
1718+
if (!equal(a->arg,b->arg))
1719+
return false;
1720+
if (a->nulltesttype!=b->nulltesttype)
1721+
return false;
1722+
return true;
1723+
}
1724+
1725+
staticbool
1726+
_equalBooleanTest(BooleanTest*a,BooleanTest*b)
1727+
{
1728+
if (!equal(a->arg,b->arg))
1729+
return false;
1730+
if (a->booltesttype!=b->booltesttype)
1731+
return false;
1732+
return true;
1733+
}
1734+
17151735
/*
17161736
* Stuff from pg_list.h
17171737
*/
@@ -2120,6 +2140,12 @@ equal(void *a, void *b)
21202140
caseT_CaseWhen:
21212141
retval=_equalCaseWhen(a,b);
21222142
break;
2143+
caseT_NullTest:
2144+
retval=_equalNullTest(a,b);
2145+
break;
2146+
caseT_BooleanTest:
2147+
retval=_equalBooleanTest(a,b);
2148+
break;
21232149
caseT_FkConstraint:
21242150
retval=_equalFkConstraint(a,b);
21252151
break;

‎src/backend/nodes/outfuncs.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
8-
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.141 2001/05/20 20:28:18 tgl Exp $
8+
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.142 2001/06/19 22:39:11 tgl Exp $
99
*
1010
* NOTES
1111
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1259,12 +1259,6 @@ _outAExpr(StringInfo str, A_Expr *node)
12591259
caseNOT:
12601260
appendStringInfo(str,"NOT ");
12611261
break;
1262-
caseISNULL:
1263-
appendStringInfo(str,"ISNULL ");
1264-
break;
1265-
caseNOTNULL:
1266-
appendStringInfo(str,"NOTNULL ");
1267-
break;
12681262
caseOP:
12691263
_outToken(str,node->opname);
12701264
appendStringInfo(str," ");
@@ -1402,6 +1396,32 @@ _outCaseWhen(StringInfo str, CaseWhen *node)
14021396
_outNode(str,node->result);
14031397
}
14041398

1399+
/*
1400+
*NullTest
1401+
*/
1402+
staticvoid
1403+
_outNullTest(StringInfostr,NullTest*node)
1404+
{
1405+
appendStringInfo(str," NULLTEST :arg ");
1406+
_outNode(str,node->arg);
1407+
1408+
appendStringInfo(str," :nulltesttype %d ",
1409+
(int)node->nulltesttype);
1410+
}
1411+
1412+
/*
1413+
*BooleanTest
1414+
*/
1415+
staticvoid
1416+
_outBooleanTest(StringInfostr,BooleanTest*node)
1417+
{
1418+
appendStringInfo(str," BOOLEANTEST :arg ");
1419+
_outNode(str,node->arg);
1420+
1421+
appendStringInfo(str," :booltesttype %d ",
1422+
(int)node->booltesttype);
1423+
}
1424+
14051425
/*
14061426
* _outNode -
14071427
* converts a Node into ascii string and append it to 'str'
@@ -1639,7 +1659,12 @@ _outNode(StringInfo str, void *obj)
16391659
caseT_CaseWhen:
16401660
_outCaseWhen(str,obj);
16411661
break;
1642-
1662+
caseT_NullTest:
1663+
_outNullTest(str,obj);
1664+
break;
1665+
caseT_BooleanTest:
1666+
_outBooleanTest(str,obj);
1667+
break;
16431668
caseT_VariableSetStmt:
16441669
break;
16451670
caseT_SelectStmt:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp