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

Commit3e22406

Browse files
committed
Finished the Between patch Christopher started.
Implements between (symmetric / asymmetric) as a node.Executes the left or right expression once, makes a Const out of theresulting Datum and executes the >=, <= portions out of the Const sets.Of course, the parser does a fair amount of preparatory work for this tohappen.Rod Taylor
1 parent7ea5f1d commit3e22406

File tree

15 files changed

+619
-35
lines changed

15 files changed

+619
-35
lines changed

‎src/backend/executor/execQual.c‎

Lines changed: 110 additions & 2 deletions
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.97 2002/07/06 20:16:35 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.98 2002/07/18 04:41:44 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -38,6 +38,9 @@
3838
#include"executor/execdebug.h"
3939
#include"executor/functions.h"
4040
#include"executor/nodeSubplan.h"
41+
#include"nodes/makefuncs.h"
42+
#include"parser/parse.h"
43+
#include"parser/parse_expr.h"
4144
#include"utils/array.h"
4245
#include"utils/builtins.h"
4346
#include"utils/fcache.h"
@@ -62,6 +65,8 @@ static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
6265
staticDatumExecEvalOr(Expr*orExpr,ExprContext*econtext,bool*isNull);
6366
staticDatumExecEvalCase(CaseExpr*caseExpr,ExprContext*econtext,
6467
bool*isNull,ExprDoneCond*isDone);
68+
staticDatumExecEvalBetweenExpr(BetweenExpr*btest,ExprContext*econtext,
69+
bool*isNull,ExprDoneCond*isDone);
6570
staticDatumExecEvalNullTest(NullTest*ntest,ExprContext*econtext,
6671
bool*isNull,ExprDoneCond*isDone);
6772
staticDatumExecEvalBooleanTest(BooleanTest*btest,ExprContext*econtext,
@@ -1188,6 +1193,104 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
11881193
return (Datum)0;
11891194
}
11901195

1196+
/* ----------------------------------------------------------------
1197+
*ExecEvalBetweenExpr
1198+
*
1199+
*Evaluate a BetweenExpr node. Result is
1200+
*a boolean. If any of the three expression
1201+
*parameters are NULL, result is NULL.
1202+
* ----------------------------------------------------------------
1203+
*/
1204+
staticDatum
1205+
ExecEvalBetweenExpr(BetweenExpr*btest,
1206+
ExprContext*econtext,
1207+
bool*isNull,
1208+
ExprDoneCond*isDone)
1209+
{
1210+
Datumexpr_result;
1211+
Datumlexpr_result;
1212+
Datumrexpr_result;
1213+
boolresult= FALSE;
1214+
Node*expr_const;
1215+
Node*lexpr_const;
1216+
Node*rexpr_const;
1217+
1218+
/* Evaluate subexpressons and Auto-return if we find a NULL */
1219+
expr_result=ExecEvalExpr(btest->expr,econtext,isNull,isDone);
1220+
if (*isNull)
1221+
return (Datum)0;
1222+
1223+
lexpr_result=ExecEvalExpr(btest->lexpr,econtext,isNull,isDone);
1224+
if (*isNull)
1225+
return (Datum)0;
1226+
1227+
rexpr_result=ExecEvalExpr(btest->rexpr,econtext,isNull,isDone);
1228+
if (*isNull)
1229+
return (Datum)0;
1230+
1231+
/*
1232+
* Make a Constant out of our newly found Datums
1233+
* Types were coerced during transformExpr to be common
1234+
*/
1235+
expr_const= (Node*)makeConst(btest->typeId,btest->typeLen,
1236+
expr_result, false,
1237+
btest->typeByVal, false, true);
1238+
1239+
lexpr_const= (Node*)makeConst(btest->typeId,btest->typeLen,
1240+
lexpr_result, false,
1241+
btest->typeByVal, false, true);
1242+
1243+
rexpr_const= (Node*)makeConst(btest->typeId,btest->typeLen,
1244+
rexpr_result, false,
1245+
btest->typeByVal, false, true);
1246+
1247+
/*
1248+
* Test the between case which for the straight forward method.
1249+
* expr >= lexpr and expr <= rexpr
1250+
*
1251+
* Of course, can't use makeA_Expr here without requiring another
1252+
* transform, so we've already prepared a gthan and lthan operator
1253+
* set in the parsing stage.
1254+
*/
1255+
btest->gthan->args=makeList2(expr_const,lexpr_const);
1256+
if (DatumGetBool(ExecEvalExpr((Node*)btest->gthan,
1257+
econtext,
1258+
isNull,isDone)))
1259+
{
1260+
btest->lthan->args=makeList2(expr_const,rexpr_const);
1261+
result=DatumGetBool(ExecEvalExpr((Node*)btest->lthan,
1262+
econtext,
1263+
isNull,isDone));
1264+
}
1265+
1266+
/*
1267+
* If this is a symmetric BETWEEN, we win a second try with the operators
1268+
* reversed. (a >= min(b,c) and a <= max(b,c))
1269+
*/
1270+
if (!result&&btest->symmetric)
1271+
{
1272+
btest->gthan->args=makeList2(expr_const,rexpr_const);
1273+
if (DatumGetBool(ExecEvalExpr((Node*)btest->gthan,
1274+
econtext,
1275+
isNull,isDone)))
1276+
{
1277+
btest->lthan->args=makeList2(expr_const,lexpr_const);
1278+
result=DatumGetBool(ExecEvalExpr((Node*)btest->lthan,
1279+
econtext,
1280+
isNull,isDone));
1281+
}
1282+
}
1283+
1284+
/* Apply NOT as necessary */
1285+
if (btest->not)
1286+
result= !result;
1287+
1288+
/* We're not returning a null */
1289+
*isNull= false;
1290+
1291+
return (BoolGetDatum(result));
1292+
}
1293+
11911294
/* ----------------------------------------------------------------
11921295
*ExecEvalNullTest
11931296
*
@@ -1524,6 +1627,12 @@ ExecEvalExpr(Node *expression,
15241627
isNull,
15251628
isDone);
15261629
break;
1630+
caseT_BetweenExpr:
1631+
retDatum=ExecEvalBetweenExpr((BetweenExpr*)expression,
1632+
econtext,
1633+
isNull,
1634+
isDone);
1635+
break;
15271636
caseT_NullTest:
15281637
retDatum=ExecEvalNullTest((NullTest*)expression,
15291638
econtext,
@@ -1536,7 +1645,6 @@ ExecEvalExpr(Node *expression,
15361645
isNull,
15371646
isDone);
15381647
break;
1539-
15401648
default:
15411649
elog(ERROR,"ExecEvalExpr: unknown expression type %d",
15421650
nodeTag(expression));

‎src/backend/nodes/copyfuncs.c‎

Lines changed: 30 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.194 2002/07/16 22:12:19 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.195 2002/07/18 04:41:44 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -999,6 +999,32 @@ _copyCaseExpr(CaseExpr *from)
999999
returnnewnode;
10001000
}
10011001

1002+
/* ----------------
1003+
* _copyBetweenExpr
1004+
* ----------------
1005+
*/
1006+
staticBetweenExpr*
1007+
_copyBetweenExpr(BetweenExpr*from)
1008+
{
1009+
BetweenExpr*newnode=makeNode(BetweenExpr);
1010+
1011+
/*
1012+
* copy remainder of node
1013+
*/
1014+
Node_Copy(from,newnode,expr);
1015+
Node_Copy(from,newnode,lexpr);
1016+
Node_Copy(from,newnode,rexpr);
1017+
Node_Copy(from,newnode,lthan);
1018+
Node_Copy(from,newnode,gthan);
1019+
newnode->symmetric=from->symmetric;
1020+
newnode->not=from->not;
1021+
newnode->typeId=from->typeId;
1022+
newnode->typeLen=from->typeLen;
1023+
newnode->typeByVal=from->typeByVal;
1024+
1025+
returnnewnode;
1026+
}
1027+
10021028
/* ----------------
10031029
*_copyCaseWhen
10041030
* ----------------
@@ -3052,6 +3078,9 @@ copyObject(void *from)
30523078
caseT_CaseExpr:
30533079
retval=_copyCaseExpr(from);
30543080
break;
3081+
caseT_BetweenExpr:
3082+
retval=_copyBetweenExpr(from);
3083+
break;
30553084
caseT_CaseWhen:
30563085
retval=_copyCaseWhen(from);
30573086
break;

‎src/backend/nodes/equalfuncs.c‎

Lines changed: 31 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.141 2002/07/16 22:12:19 tgl Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.142 2002/07/18 04:41:44 momjian Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -1769,6 +1769,33 @@ _equalCaseExpr(CaseExpr *a, CaseExpr *b)
17691769
return true;
17701770
}
17711771

1772+
staticbool
1773+
_equalBetweenExpr(BetweenExpr*a,BetweenExpr*b)
1774+
{
1775+
if (!equal(a->expr,b->expr))
1776+
return false;
1777+
if (!equal(a->lexpr,b->lexpr))
1778+
return false;
1779+
if (!equal(a->rexpr,b->rexpr))
1780+
return false;
1781+
if (!equal(a->lthan,b->lthan))
1782+
return false;
1783+
if (!equal(a->gthan,b->gthan))
1784+
return false;
1785+
if (a->symmetric!=b->symmetric)
1786+
return false;
1787+
if (a->not!=b->not)
1788+
return false;
1789+
if (a->typeId!=b->typeId)
1790+
return false;
1791+
if (a->typeLen!=b->typeLen)
1792+
return false;
1793+
if (a->typeByVal!=b->typeByVal)
1794+
return false;
1795+
1796+
return true;
1797+
}
1798+
17721799
staticbool
17731800
_equalCaseWhen(CaseWhen*a,CaseWhen*b)
17741801
{
@@ -2217,6 +2244,9 @@ equal(void *a, void *b)
22172244
caseT_CaseExpr:
22182245
retval=_equalCaseExpr(a,b);
22192246
break;
2247+
caseT_BetweenExpr:
2248+
retval=_equalBetweenExpr(a,b);
2249+
break;
22202250
caseT_CaseWhen:
22212251
retval=_equalCaseWhen(a,b);
22222252
break;

‎src/backend/nodes/outfuncs.c‎

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2002, 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.163 2002/07/16 22:12:19 tgl Exp $
8+
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.164 2002/07/18 04:41:44 momjian Exp $
99
*
1010
* NOTES
1111
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1483,6 +1483,38 @@ _outCaseWhen(StringInfo str, CaseWhen *node)
14831483
_outNode(str,node->result);
14841484
}
14851485

1486+
/*
1487+
* BetweenExpr
1488+
*/
1489+
staticvoid
1490+
_outBetweenExpr(StringInfostr,BetweenExpr*node)
1491+
{
1492+
appendStringInfo(str," BETWEENEXPR :expr ");
1493+
_outNode(str,node->expr);
1494+
1495+
appendStringInfo(str," :not %s",
1496+
booltostr(node->not));
1497+
1498+
appendStringInfo(str," :symmetric %s",
1499+
booltostr(node->symmetric));
1500+
1501+
appendStringInfo(str," :lexpr ");
1502+
_outNode(str,node->lexpr);
1503+
1504+
appendStringInfo(str," :rexpr ");
1505+
_outNode(str,node->rexpr);
1506+
1507+
appendStringInfo(str," :gthan ");
1508+
_outNode(str,node->gthan);
1509+
1510+
appendStringInfo(str," :lthan ");
1511+
_outNode(str,node->lthan);
1512+
1513+
appendStringInfo(str," :typeid %u :typelen %d :typebyval %s",
1514+
node->typeId,node->typeLen,
1515+
booltostr(node->typeByVal));
1516+
}
1517+
14861518
/*
14871519
*NullTest
14881520
*/
@@ -1767,6 +1799,9 @@ _outNode(StringInfo str, void *obj)
17671799
caseT_CaseExpr:
17681800
_outCaseExpr(str,obj);
17691801
break;
1802+
caseT_BetweenExpr:
1803+
_outBetweenExpr(str,obj);
1804+
break;
17701805
caseT_CaseWhen:
17711806
_outCaseWhen(str,obj);
17721807
break;

‎src/backend/nodes/readfuncs.c‎

Lines changed: 50 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/nodes/readfuncs.c,v 1.124 2002/07/04 15:23:54 thomas Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.125 2002/07/18 04:41:45 momjian Exp $
1212
*
1313
* NOTES
1414
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -881,6 +881,53 @@ _readCaseWhen(void)
881881
returnlocal_node;
882882
}
883883

884+
staticBetweenExpr*
885+
_readBetweenExpr(void)
886+
{
887+
BetweenExpr*local_node;
888+
char*token;
889+
intlength;
890+
891+
local_node=makeNode(BetweenExpr);
892+
893+
token=pg_strtok(&length);/* eat :expr */
894+
local_node->expr=nodeRead(true);
895+
896+
token=pg_strtok(&length);/* eat :not */
897+
token=pg_strtok(&length);/* get not */
898+
local_node->not=strtobool(token);
899+
900+
token=pg_strtok(&length);/* eat :symmetric */
901+
token=pg_strtok(&length);/* get symmetric */
902+
local_node->symmetric=strtobool(token);
903+
904+
token=pg_strtok(&length);/* eat :lexpr */
905+
local_node->lexpr=nodeRead(true);
906+
907+
token=pg_strtok(&length);/* eat :rexpr */
908+
local_node->rexpr=nodeRead(true);
909+
910+
token=pg_strtok(&length);/* eat :gthan */
911+
local_node->gthan=nodeRead(true);
912+
913+
token=pg_strtok(&length);/* eat :lthan */
914+
local_node->lthan=nodeRead(true);
915+
916+
token=pg_strtok(&length);/* eat :typeid */
917+
token=pg_strtok(&length);/* get typeid */
918+
local_node->typeId=atooid(token);
919+
920+
token=pg_strtok(&length);/* eat :typelen */
921+
token=pg_strtok(&length);/* get typelen */
922+
local_node->typeLen=atoui(token);
923+
924+
token=pg_strtok(&length);/* eat :typebyval */
925+
token=pg_strtok(&length);/* get typebyval */
926+
local_node->typeByVal=strtobool(token);
927+
928+
returnlocal_node;
929+
}
930+
884931
/* ----------------
885932
*_readNullTest
886933
*
@@ -2132,6 +2179,8 @@ parsePlanString(void)
21322179
return_value=_readNullTest();
21332180
elseif (length==11&&strncmp(token,"BOOLEANTEST",length)==0)
21342181
return_value=_readBooleanTest();
2182+
elseif (length==11&&strncmp(token,"BETWEENEXPR",length)==0)
2183+
return_value=_readBetweenExpr();
21352184
else
21362185
elog(ERROR,"badly formatted planstring \"%.10s\"...",token);
21372186

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp