@@ -1011,15 +1011,20 @@ static void
1011
1011
UserTableUpdateOpenIndexes ()
1012
1012
{
1013
1013
List * recheckIndexes = NIL ;
1014
+ #if PG_VERSION_NUM >=120000
1015
+ HeapTuple tuple = ExecFetchSlotHeapTuple (slot , true, NULL );
1016
+ #else
1017
+ HeapTuple tuple = slot -> tts_tuple ;
1018
+ #endif
1014
1019
1015
1020
/* HOT update does not require index inserts */
1016
- if (HeapTupleIsHeapOnly (slot -> tts_tuple ))
1021
+ if (HeapTupleIsHeapOnly (tuple ))
1017
1022
return ;
1018
1023
1019
1024
if (estate -> es_result_relation_info -> ri_NumIndices > 0 )
1020
1025
{
1021
1026
recheckIndexes = ExecInsertIndexTuples (slot ,
1022
- & slot -> tts_tuple -> t_self ,
1027
+ & tuple -> t_self ,
1023
1028
estate , false, NULL , NIL );
1024
1029
1025
1030
if (recheckIndexes != NIL )
@@ -1034,7 +1039,7 @@ static void begin_batch_insert(Oid oid)
1034
1039
{
1035
1040
ResultRelInfo * resultRelInfo ;
1036
1041
1037
- rel = heap_open (oid , NoLock );
1042
+ rel = heap_open (oid , RowExclusiveLock );
1038
1043
1039
1044
PushActiveSnapshot (GetTransactionSnapshot ());
1040
1045
@@ -1049,7 +1054,9 @@ static void begin_batch_insert(Oid oid)
1049
1054
estate -> es_num_result_relations = 1 ;
1050
1055
estate -> es_result_relation_info = resultRelInfo ;
1051
1056
ExecOpenIndices (estate -> es_result_relation_info , false);
1052
- #if PG_VERSION_NUM >=110000
1057
+ #if PG_VERSION_NUM >=120000
1058
+ slot = ExecInitExtraTupleSlot (estate , RelationGetDescr (rel ), & TTSOpsHeapTuple );
1059
+ #elif PG_VERSION_NUM >=110000
1053
1060
slot = ExecInitExtraTupleSlot (estate , RelationGetDescr (rel ));
1054
1061
#else
1055
1062
slot = ExecInitExtraTupleSlot (estate );
@@ -1060,8 +1067,13 @@ static void begin_batch_insert(Oid oid)
1060
1067
static void insert_tuple (Datum * values , bool * nulls )
1061
1068
{
1062
1069
HeapTuple tup = heap_form_tuple (RelationGetDescr (rel ), values , nulls );
1070
+ #if PG_VERSION_NUM >=120000
1071
+ ExecStoreHeapTuple (tup , slot , true);
1072
+ simple_heap_insert (rel , ExecFetchSlotHeapTuple (slot , true, NULL ));
1073
+ #else
1063
1074
ExecStoreTuple (tup , slot , InvalidBuffer , true);
1064
1075
simple_heap_insert (rel , slot -> tts_tuple );
1076
+ #endif
1065
1077
UserTableUpdateOpenIndexes ();
1066
1078
}
1067
1079
@@ -2976,7 +2988,11 @@ Datum vops_unnest(PG_FUNCTION_ARGS)
2976
2988
user_ctx -> nulls = (bool * )palloc (sizeof (bool )* n_attrs );
2977
2989
user_ctx -> types = (vops_type * )palloc (sizeof (vops_type )* n_attrs );
2978
2990
user_ctx -> tiles = (vops_tile_hdr * * )palloc (sizeof (vops_tile_hdr * )* n_attrs );
2991
+ #if PG_VERSION_NUM >=120000
2992
+ user_ctx -> desc = CreateTemplateTupleDesc (n_attrs );
2993
+ #else
2979
2994
user_ctx -> desc = CreateTemplateTupleDesc (n_attrs , false);
2995
+ #endif
2980
2996
func_ctx -> user_fctx = user_ctx ;
2981
2997
user_ctx -> n_attrs = n_attrs ;
2982
2998
user_ctx -> tile_pos = 0 ;
@@ -3535,10 +3551,6 @@ vops_pullvars_walker(Node *node, vops_pullvar_context *ctx)
3535
3551
ctx -> scope = scope ;
3536
3552
node = (Node * )from -> fromlist ;
3537
3553
}
3538
- else if (IsA (node , Query ))
3539
- {
3540
- return query_tree_walker ((Query * )node , vops_pullvars_walker , ctx , 0 );
3541
- }
3542
3554
(void ) expression_tree_walker (node , vops_pullvars_walker , ctx );
3543
3555
ctx -> scope = scope ;
3544
3556
return false;
@@ -3652,6 +3664,42 @@ vops_add_literal_type_casts(Node* node, Const** consts)
3652
3664
return node ;
3653
3665
}
3654
3666
3667
+ static RangeVar *
3668
+ vops_get_join_rangevar (Node * node , int * relno )
3669
+ {
3670
+ if (IsA (node , JoinExpr ))
3671
+ {
3672
+ RangeVar * rv ;
3673
+ JoinExpr * join = (JoinExpr * )node ;
3674
+ rv = vops_get_join_rangevar (join -> larg , relno );
3675
+ if (rv != NULL )
3676
+ return rv ;
3677
+ rv = vops_get_join_rangevar (join -> rarg , relno );
3678
+ if (rv != NULL )
3679
+ return rv ;
3680
+ }
3681
+ else
3682
+ {
3683
+ Assert (IsA (node , RangeVar ));
3684
+ if (-- * relno == 0 )
3685
+ return (RangeVar * )node ;
3686
+ }
3687
+ return NULL ;
3688
+ }
3689
+
3690
+ static RangeVar *
3691
+ vops_get_rangevar (List * from , int relno )
3692
+ {
3693
+ ListCell * cell ;
3694
+ foreach (cell , from )
3695
+ {
3696
+ Node * node = (Node * )lfirst (cell );
3697
+ RangeVar * rv = vops_get_join_rangevar (node , & relno );
3698
+ if (rv != NULL )
3699
+ return rv ;
3700
+ }
3701
+ Assert (false);
3702
+ }
3655
3703
/*
3656
3704
* Try to substitute tables with their VOPS projections.
3657
3705
* Criterias for such substitution:
@@ -3685,7 +3733,7 @@ vops_substitute_tables_with_projections(char const* queryString, Query *query)
3685
3733
pullvar_ctx .consts = (Const * * )palloc0 ((strlen (queryString ) + 1 )* sizeof (Const * ));
3686
3734
pullvar_ctx .scope = SCOPE_DEFAULT ;
3687
3735
pullvar_ctx .refs = palloc0 (n_rels * sizeof (vops_table_refs ));
3688
- query_tree_walker (query , vops_pullvars_walker , & pullvar_ctx , 0 );
3736
+ query_tree_walker (query , vops_pullvars_walker , & pullvar_ctx , QTW_IGNORE_CTE_SUBQUERIES | QTW_IGNORE_RANGE_TABLE );
3689
3737
3690
3738
SPI_connect ();
3691
3739
@@ -3768,7 +3816,10 @@ vops_substitute_tables_with_projections(char const* queryString, Query *query)
3768
3816
}
3769
3817
/* Replace table with partition */
3770
3818
elog (DEBUG1 , "Use projection %s instead of table %d" , projectionName , rte -> relid );
3771
- rv = list_nth_node (RangeVar , select -> fromClause , fromno - 1 );
3819
+ rv = vops_get_rangevar (select -> fromClause , fromno );
3820
+ Assert (rv != NULL );
3821
+ if (rv -> alias == NULL )
3822
+ rv -> alias = makeAlias (rv -> relname , NULL );
3772
3823
rv -> relname = pstrdup (projectionName );
3773
3824
3774
3825
/* Update vector/scalar bitmap sets for this query for this projection */
@@ -3949,8 +4000,13 @@ static void vops_explain_hook(Query *query,
3949
4000
params == NULL ) /* do not support prepared statements yet */
3950
4001
{
3951
4002
char * explain = pstrdup (queryString );
3952
- char * select = strstr (explain , "select" );
3953
- size_t prefix = (select != NULL ) ? (select - explain ) : 7 ;
4003
+ char * select ;
4004
+ size_t prefix ;
4005
+ select = strstr (explain , "select" );
4006
+ if (select == NULL ) {
4007
+ select = strstr (explain , "SELECT" );
4008
+ }
4009
+ prefix = (select != NULL ) ? (select - explain ) : 7 ;
3954
4010
memset (explain , ' ' , prefix ); /* clear "explain" prefix: we need to preseve node locations */
3955
4011
vops_substitute_tables_with_projections (explain , query );
3956
4012
}
0 commit comments