@@ -1011,15 +1011,20 @@ static void
10111011UserTableUpdateOpenIndexes ()
10121012{
10131013List * 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
10141019
10151020/* HOT update does not require index inserts */
1016- if (HeapTupleIsHeapOnly (slot -> tts_tuple ))
1021+ if (HeapTupleIsHeapOnly (tuple ))
10171022return ;
10181023
10191024if (estate -> es_result_relation_info -> ri_NumIndices > 0 )
10201025{
10211026recheckIndexes = ExecInsertIndexTuples (slot ,
1022- & slot -> tts_tuple -> t_self ,
1027+ & tuple -> t_self ,
10231028estate , false,NULL ,NIL );
10241029
10251030if (recheckIndexes != NIL )
@@ -1034,7 +1039,7 @@ static void begin_batch_insert(Oid oid)
10341039{
10351040ResultRelInfo * resultRelInfo ;
10361041
1037- rel = heap_open (oid ,NoLock );
1042+ rel = heap_open (oid ,RowExclusiveLock );
10381043
10391044PushActiveSnapshot (GetTransactionSnapshot ());
10401045
@@ -1049,7 +1054,9 @@ static void begin_batch_insert(Oid oid)
10491054estate -> es_num_result_relations = 1 ;
10501055estate -> es_result_relation_info = resultRelInfo ;
10511056ExecOpenIndices (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
10531060slot = ExecInitExtraTupleSlot (estate ,RelationGetDescr (rel ));
10541061#else
10551062slot = ExecInitExtraTupleSlot (estate );
@@ -1060,8 +1067,13 @@ static void begin_batch_insert(Oid oid)
10601067static void insert_tuple (Datum * values ,bool * nulls )
10611068{
10621069HeapTuple 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
10631074ExecStoreTuple (tup ,slot ,InvalidBuffer , true);
10641075simple_heap_insert (rel ,slot -> tts_tuple );
1076+ #endif
10651077UserTableUpdateOpenIndexes ();
10661078}
10671079
@@ -2976,7 +2988,11 @@ Datum vops_unnest(PG_FUNCTION_ARGS)
29762988user_ctx -> nulls = (bool * )palloc (sizeof (bool )* n_attrs );
29772989user_ctx -> types = (vops_type * )palloc (sizeof (vops_type )* n_attrs );
29782990user_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
29792994user_ctx -> desc = CreateTemplateTupleDesc (n_attrs , false);
2995+ #endif
29802996func_ctx -> user_fctx = user_ctx ;
29812997user_ctx -> n_attrs = n_attrs ;
29822998user_ctx -> tile_pos = 0 ;
@@ -3535,10 +3551,6 @@ vops_pullvars_walker(Node *node, vops_pullvar_context *ctx)
35353551ctx -> scope = scope ;
35363552node = (Node * )from -> fromlist ;
35373553}
3538- else if (IsA (node ,Query ))
3539- {
3540- return query_tree_walker ((Query * )node ,vops_pullvars_walker ,ctx ,0 );
3541- }
35423554(void )expression_tree_walker (node ,vops_pullvars_walker ,ctx );
35433555ctx -> scope = scope ;
35443556return false;
@@ -3652,6 +3664,42 @@ vops_add_literal_type_casts(Node* node, Const** consts)
36523664return node ;
36533665}
36543666
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+ }
36553703/*
36563704 * Try to substitute tables with their VOPS projections.
36573705 * Criterias for such substitution:
@@ -3685,7 +3733,7 @@ vops_substitute_tables_with_projections(char const* queryString, Query *query)
36853733pullvar_ctx .consts = (Const * * )palloc0 ((strlen (queryString )+ 1 )* sizeof (Const * ));
36863734pullvar_ctx .scope = SCOPE_DEFAULT ;
36873735pullvar_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 );
36893737
36903738SPI_connect ();
36913739
@@ -3768,7 +3816,10 @@ vops_substitute_tables_with_projections(char const* queryString, Query *query)
37683816}
37693817/* Replace table with partition */
37703818elog (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 );
37723823rv -> relname = pstrdup (projectionName );
37733824
37743825/* Update vector/scalar bitmap sets for this query for this projection */
@@ -3949,8 +4000,13 @@ static void vops_explain_hook(Query *query,
39494000params == NULL )/* do not support prepared statements yet */
39504001{
39514002char * 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 ;
39544010memset (explain ,' ' ,prefix );/* clear "explain" prefix: we need to preseve node locations */
39554011vops_substitute_tables_with_projections (explain ,query );
39564012}