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

Commit1c5b902

Browse files
committed
Fix problem in which sloppily-coded test in ExecInitIndexScan would
think that both sides of indexqual look like index keys. An example iscreate table inside (f1 float8 primary key);create table outside (g1 float8, g2 float8);select * from inside,outside where f1 = atan2(g1+1, g2);ERROR: ExecInitIndexScan: both left and right ops are rel-vars(note that failure is potentially platform-dependent). Solution is acleanup I had had in mind to make anyway: functional index keys shouldbe represented as Var nodes in the fixed indexqual, just like regularindex keys.
1 parent1c8244e commit1c5b902

File tree

2 files changed

+36
-60
lines changed

2 files changed

+36
-60
lines changed

‎src/backend/executor/nodeIndexscan.c

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.49 2000/04/12 17:15:09 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.50 2000/05/23 16:56:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -734,8 +734,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
734734
*/
735735
for (j=0;j<n_keys;j++)
736736
{
737-
Expr*clause;/* onepart of index qual */
738-
Oper*op;/* operator used inscan.. */
737+
Expr*clause;/* oneclause of index qual */
738+
Oper*op;/* operator used inclause */
739739
Node*leftop;/* expr on lhs of operator */
740740
Node*rightop;/* expr on rhs ... */
741741
bits16flags=0;
@@ -794,6 +794,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
794794
*/
795795

796796
scanvar=NO_OP;
797+
run_keys[j]=NO_OP;
797798

798799
/* ----------------
799800
*determine information in leftop
@@ -803,7 +804,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
803804

804805
Assert(leftop!=NULL);
805806

806-
if (IsA(leftop,Var)&&var_is_rel((Var*)leftop))
807+
if (IsA(leftop,Var)&&var_is_rel((Var*)leftop))
807808
{
808809
/* ----------------
809810
*if the leftop is a "rel-var", then it means
@@ -814,28 +815,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
814815
varattno= ((Var*)leftop)->varattno;
815816
scanvar=LEFT_OP;
816817
}
817-
elseif (is_funcclause(leftop)&&
818-
var_is_rel(lfirst(((Expr*)leftop)->args)))
819-
{
820-
/* ----------------
821-
*if the leftop is a func node then it means
822-
*it identifies the value to place in our scan key.
823-
*Since functional indices have only one attribute
824-
*the attno must always be set to 1.
825-
* ----------------
826-
*/
827-
varattno=1;
828-
scanvar=LEFT_OP;
829-
}
830818
elseif (IsA(leftop,Const))
831819
{
832820
/* ----------------
833821
*if the leftop is a const node then it means
834822
*it identifies the value to place in our scan key.
835823
* ----------------
836824
*/
837-
run_keys[j]=NO_OP;
838825
scanvalue= ((Const*)leftop)->constvalue;
826+
if (((Const*)leftop)->constisnull)
827+
flags |=SK_ISNULL;
839828
}
840829
elseif (IsA(leftop,Param))
841830
{
@@ -850,32 +839,31 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
850839
/* Life was so easy before ... subselects */
851840
if (((Param*)leftop)->paramkind==PARAM_EXEC)
852841
{
842+
/* treat Param as runtime key */
853843
have_runtime_keys= true;
854844
run_keys[j]=LEFT_OP;
855845
execParam=lappendi(execParam, ((Param*)leftop)->paramid);
856846
}
857847
else
858848
{
849+
/* treat Param like a constant */
859850
scanvalue=ExecEvalParam((Param*)leftop,
860851
scanstate->cstate.cs_ExprContext,
861852
&isnull);
862853
if (isnull)
863854
flags |=SK_ISNULL;
864-
865-
run_keys[j]=NO_OP;
866855
}
867856
}
868857
else
869858
{
870859
/* ----------------
871-
*otherwise, the leftop containsinformation usable
860+
*otherwise, the leftop containsan expression evaluable
872861
*at runtime to figure out the value to place in our
873862
*scan key.
874863
* ----------------
875864
*/
876865
have_runtime_keys= true;
877866
run_keys[j]=LEFT_OP;
878-
scanvalue=Int32GetDatum((int32) true);
879867
}
880868

881869
/* ----------------
@@ -886,7 +874,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
886874

887875
Assert(rightop!=NULL);
888876

889-
if (IsA(rightop,Var)&&var_is_rel((Var*)rightop))
877+
if (IsA(rightop,Var)&&var_is_rel((Var*)rightop))
890878
{
891879
/* ----------------
892880
*here we make sure only one op identifies the
@@ -906,32 +894,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
906894
varattno= ((Var*)rightop)->varattno;
907895
scanvar=RIGHT_OP;
908896
}
909-
elseif (is_funcclause(rightop)&&
910-
var_is_rel(lfirst(((Expr*)rightop)->args)))
911-
{
912-
/* ----------------
913-
*if the rightop is a func node then it means
914-
*it identifies the value to place in our scan key.
915-
*Since functional indices have only one attribute
916-
*the attno must always be set to 1.
917-
* ----------------
918-
*/
919-
if (scanvar==LEFT_OP)
920-
elog(ERROR,"ExecInitIndexScan: %s",
921-
"both left and right ops are rel-vars");
922-
923-
varattno=1;
924-
scanvar=RIGHT_OP;
925-
}
926897
elseif (IsA(rightop,Const))
927898
{
928899
/* ----------------
929900
*if the rightop is a const node then it means
930901
*it identifies the value to place in our scan key.
931902
* ----------------
932903
*/
933-
run_keys[j]=NO_OP;
934904
scanvalue= ((Const*)rightop)->constvalue;
905+
if (((Const*)rightop)->constisnull)
906+
flags |=SK_ISNULL;
935907
}
936908
elseif (IsA(rightop,Param))
937909
{
@@ -946,32 +918,31 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
946918
/* Life was so easy before ... subselects */
947919
if (((Param*)rightop)->paramkind==PARAM_EXEC)
948920
{
921+
/* treat Param as runtime key */
949922
have_runtime_keys= true;
950923
run_keys[j]=RIGHT_OP;
951924
execParam=lappendi(execParam, ((Param*)rightop)->paramid);
952925
}
953926
else
954927
{
928+
/* treat Param like a constant */
955929
scanvalue=ExecEvalParam((Param*)rightop,
956930
scanstate->cstate.cs_ExprContext,
957931
&isnull);
958932
if (isnull)
959933
flags |=SK_ISNULL;
960-
961-
run_keys[j]=NO_OP;
962934
}
963935
}
964936
else
965937
{
966938
/* ----------------
967-
*otherwise, the rightop containsinformation usable
939+
*otherwise, the rightop containsan expression evaluable
968940
*at runtime to figure out the value to place in our
969941
*scan key.
970942
* ----------------
971943
*/
972944
have_runtime_keys= true;
973945
run_keys[j]=RIGHT_OP;
974-
scanvalue=Int32GetDatum((int32) true);
975946
}
976947

977948
/* ----------------
@@ -992,7 +963,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
992963
varattno,/* attribute number to
993964
* scan */
994965
(RegProcedure)opid,/* reg proc to use */
995-
(Datum)scanvalue);/* constant */
966+
scanvalue);/* constant */
996967
}
997968

998969
/* ----------------

‎src/backend/optimizer/plan/createplan.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.89 2000/04/12 17:15:21 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.90 2000/05/23 16:56:36 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -27,6 +27,7 @@
2727
#include"optimizer/planmain.h"
2828
#include"optimizer/restrictinfo.h"
2929
#include"optimizer/tlist.h"
30+
#include"parser/parse_expr.h"
3031
#include"utils/lsyscache.h"
3132
#include"utils/syscache.h"
3233

@@ -722,7 +723,7 @@ create_hashjoin_node(HashPath *best_path,
722723
* machinery needs.
723724
*
724725
* We have three tasks here:
725-
**Var nodes representing index keys must havevarattnoequal to the
726+
**Index keys must be represented by Var nodes withvarattnoset to the
726727
* index's attribute number, not the attribute number in the original rel.
727728
** indxpath.c may have selected an index that is binary-compatible with
728729
* the actual expression operator, but not exactly the same datatype.
@@ -789,7 +790,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
789790
* Fix the sublist of indexquals to be used in a particular scan.
790791
*
791792
* For each qual clause, commute if needed to put the indexkey operand on the
792-
* left, and thenchange itsvarno. (We do not need to change the other side
793+
* left, and thenfix itsvarattno. (We do not need to change the other side
793794
* of the clause.)Also change the operator if necessary.
794795
*/
795796
staticList*
@@ -863,8 +864,16 @@ static Node *
863864
fix_indxqual_operand(Node*node,intbaserelid,Form_pg_indexindex,
864865
Oid*opclass)
865866
{
867+
/*
868+
* We represent index keys by Var nodes having the varno of the base
869+
* table but varattno equal to the index's attribute number (index
870+
* column position). This is a bit hokey ... would be cleaner to use
871+
* a special-purpose node type that could not be mistaken for a regular
872+
* Var. But it will do for now.
873+
*/
866874
if (IsA(node,Var))
867875
{
876+
/* If it's a var, find which index key position it occupies */
868877
if (((Var*)node)->varno==baserelid)
869878
{
870879
intvaratt= ((Var*)node)->varattno;
@@ -877,6 +886,7 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index,
877886
Node*newnode=copyObject(node);
878887

879888
((Var*)newnode)->varattno=pos+1;
889+
/* return the correct opclass, too */
880890
*opclass=index->indclass[pos];
881891
returnnewnode;
882892
}
@@ -890,22 +900,17 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index,
890900
}
891901

892902
/*
893-
* Else, it must be a func expression representing a functional index.
894-
*
895-
* Currently, there is no need for us to do anything here for functional
896-
* indexes. If nodeIndexscan.c sees a func clause as the left or
897-
* right-hand toplevel operand of an indexqual, it assumes that that
898-
* is a reference to the functional index's value and makes the
899-
* appropriate substitution. (It would be cleaner to make the
900-
* substitution here, I think --- suspect this issue if a join clause
901-
* involving a function call misbehaves...)
903+
* Else, it must be a func expression matching a functional index.
904+
* Since we currently only support single-column functional indexes,
905+
* the returned varattno must be 1.
902906
*/
903907

908+
Assert(is_funcclause(node));/* not a very thorough check, but easy */
909+
904910
/* indclass[0] is the only class of a functional index */
905911
*opclass=index->indclass[0];
906912

907-
/* return the unmodified node */
908-
returnnode;
913+
return (Node*)makeVar(baserelid,1,exprType(node),-1,0);
909914
}
910915

911916
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp