@@ -968,6 +968,21 @@ LAST_AGG(bool,BOOL,BOOL_PAYLOAD)
968
968
FIRST_FUNC (bool ,Bool ,first ,< ,BOOL_PAYLOAD )
969
969
FIRST_FUNC (bool ,Bool ,last ,> ,BOOL_PAYLOAD )
970
970
971
+ PG_FUNCTION_INFO_V1 (vops_count_accumulate );
972
+ Datum vops_count_accumulate (PG_FUNCTION_ARGS )
973
+ {
974
+ vops_tile_hdr * opd = (vops_tile_hdr * )PG_GETARG_POINTER (1 );
975
+ int64 count = PG_GETARG_INT64 (0 );
976
+ uint64 mask = filter_mask & ~opd -> empty_mask ;
977
+ int i ;
978
+ for (i = 0 ; i < TILE_SIZE ; i ++ ) {
979
+ if (mask & ((uint64 )1 << i )) {
980
+ count += 1 ;
981
+ }
982
+ }
983
+ PG_RETURN_INT64 (count );
984
+ }
985
+
971
986
PG_FUNCTION_INFO_V1 (vops_count_any_accumulate );
972
987
Datum vops_count_any_accumulate (PG_FUNCTION_ARGS )
973
988
{
@@ -1019,8 +1034,8 @@ Datum vops_count_extend(PG_FUNCTION_ARGS)
1019
1034
PG_RETURN_POINTER (state );
1020
1035
}
1021
1036
1022
- PG_FUNCTION_INFO_V1 (vops_count_accumulate );
1023
- Datum vops_count_accumulate (PG_FUNCTION_ARGS )
1037
+ PG_FUNCTION_INFO_V1 (vops_count_all_accumulate );
1038
+ Datum vops_count_all_accumulate (PG_FUNCTION_ARGS )
1024
1039
{
1025
1040
int64 count = PG_GETARG_INT64 (0 );
1026
1041
int i ;
@@ -3747,36 +3762,71 @@ static Oid filter_oid;
3747
3762
static Oid vops_and_oid ;
3748
3763
static Oid vops_or_oid ;
3749
3764
static Oid vops_not_oid ;
3750
- static Oid countall_oid ;
3765
+ static Oid vcount_oid ;
3751
3766
static Oid count_oid ;
3752
3767
static Oid is_null_oid ;
3753
3768
static Oid is_not_null_oid ;
3754
3769
static Oid coalesce_oids [VOPS_LAST ];
3755
3770
3756
3771
typedef struct
3757
3772
{
3758
- Aggref * countall ;
3759
- bool has_vector_ops ;
3760
- } vops_mutator_context ;
3773
+ int varno ;
3774
+ int varattno ;
3775
+ int vartype ;
3776
+ } vops_var ;
3777
+
3778
+ static bool
3779
+ is_select_from_vops_projection (Query * query , vops_var * var )
3780
+ {
3781
+ int relno ;
3782
+ int n_rels = list_length (query -> rtable );
3783
+ for (relno = 1 ; relno <= n_rels ; relno ++ )
3784
+ {
3785
+ RangeTblEntry * rte = list_nth_node (RangeTblEntry , query -> rtable , relno - 1 );
3786
+ if (rte -> rtekind == RTE_RELATION )
3787
+ {
3788
+ Relation rel = table_open (rte -> relid , NoLock ); /* Assume we already have adequate lock */
3789
+ int attno ;
3790
+ for (attno = 1 ; attno <= rel -> rd_att -> natts ; attno ++ )
3791
+ {
3792
+ Oid typid = TupleDescAttr (rel -> rd_att , attno - 1 )-> atttypid ;
3793
+ if (is_vops_type (typid ))
3794
+ {
3795
+ table_close (rel , NoLock );
3796
+ var -> varno = relno ;
3797
+ var -> varattno = attno ;
3798
+ var -> vartype = typid ;
3799
+ return true;
3800
+ }
3801
+ }
3802
+ table_close (rel , NoLock );
3803
+ }
3804
+ }
3805
+ return false;
3806
+ }
3807
+
3808
+
3761
3809
3762
3810
static Node *
3763
3811
vops_expression_tree_mutator (Node * node , void * context )
3764
3812
{
3765
- vops_mutator_context * ctx = (vops_mutator_context * )context ;
3813
+ vops_var * var = (vops_var * )context ;
3766
3814
if (node == NULL )
3767
3815
{
3768
3816
return NULL ;
3769
3817
}
3770
3818
if (IsA (node , Query ))
3771
3819
{
3772
- vops_mutator_context save_ctx = * ctx ;
3773
- ctx -> countall = NULL ;
3774
- ctx -> has_vector_ops = false;
3775
- node = (Node * ) query_tree_mutator ((Query * ) node ,
3776
- vops_expression_tree_mutator ,
3777
- context ,
3778
- QTW_DONT_COPY_QUERY );
3779
- * (vops_mutator_context * )context = save_ctx ; /* restore query context */
3820
+ vops_var save_var = * var ;
3821
+ Query * query = (Query * )node ;
3822
+ if (is_select_from_vops_projection (query , var ))
3823
+ {
3824
+ node = (Node * ) query_tree_mutator (query ,
3825
+ vops_expression_tree_mutator ,
3826
+ context ,
3827
+ QTW_DONT_COPY_QUERY );
3828
+ * var = save_var ; /* restore query context */
3829
+ }
3780
3830
return node ;
3781
3831
}
3782
3832
/* depth first traversal */
@@ -3851,11 +3901,6 @@ vops_expression_tree_mutator(Node *node, void *context)
3851
3901
NullTest * test = (NullTest * )node ;
3852
3902
if (!test -> argisrow && is_vops_type (exprType ((Node * )test -> arg )))
3853
3903
{
3854
- ctx -> has_vector_ops = true;
3855
- if (ctx -> countall ) {
3856
- ctx -> countall -> aggfnoid = countall_oid ;
3857
- ctx -> countall = NULL ;
3858
- }
3859
3904
return (Node * )makeFuncExpr (filter_oid , BOOLOID ,
3860
3905
list_make1 (makeFuncExpr (test -> nulltesttype == IS_NULL
3861
3906
? is_null_oid
@@ -3867,35 +3912,15 @@ vops_expression_tree_mutator(Node *node, void *context)
3867
3912
InvalidOid , InvalidOid , COERCE_EXPLICIT_CALL );
3868
3913
}
3869
3914
}
3870
- else if (IsA (node , FuncExpr ) && !ctx -> has_vector_ops && ((FuncExpr * )node )-> funcid == filter_oid )
3871
- {
3872
- ctx -> has_vector_ops = true;
3873
- if (ctx -> countall ) {
3874
- ctx -> countall -> aggfnoid = countall_oid ;
3875
- ctx -> countall = NULL ;
3876
- }
3877
- }
3878
3915
else if (IsA (node , Aggref ))
3879
3916
{
3880
3917
Aggref * agg = (Aggref * )node ;
3881
3918
if (agg -> aggfnoid == count_oid ) {
3882
3919
Assert (agg -> aggstar );
3883
- if (ctx -> has_vector_ops ) {
3884
- agg -> aggfnoid = countall_oid ;
3885
- ctx -> countall = NULL ;
3886
- } else {
3887
- ctx -> countall = agg ;
3888
- }
3889
- } else if (!agg -> aggstar && !ctx -> has_vector_ops ) {
3890
- Assert (list_length (agg -> aggargtypes ) >= 1 );
3891
- if (is_vops_type (linitial_oid (agg -> aggargtypes )))
3892
- {
3893
- ctx -> has_vector_ops = true;
3894
- if (ctx -> countall ) {
3895
- ctx -> countall -> aggfnoid = countall_oid ;
3896
- ctx -> countall = NULL ;
3897
- }
3898
- }
3920
+ agg -> aggfnoid = vcount_oid ;
3921
+ agg -> aggstar = false;
3922
+ agg -> aggargtypes = list_make1_oid (var -> vartype );
3923
+ agg -> args = list_make1 (makeTargetEntry ((Expr * )makeVar (var -> varno , var -> varattno , var -> vartype , -1 , 0 , 0 ), 1 , NULL , false));
3899
3924
}
3900
3925
}
3901
3926
else if (IsA (node , CoalesceExpr ))
@@ -4490,7 +4515,7 @@ vops_resolve_functions(void)
4490
4515
vops_or_oid = LookupFuncName (list_make1 (makeString ("vops_bool_or" )), 2 , profile , false);
4491
4516
vops_not_oid = LookupFuncName (list_make1 (makeString ("vops_bool_not" )), 1 , profile , false);
4492
4517
count_oid = LookupFuncName (list_make1 (makeString ("count" )), 0 , profile , false);
4493
- countall_oid = LookupFuncName (list_make1 (makeString ("countall " )), 0 , profile , false);
4518
+ vcount_oid = LookupFuncName (list_make1 (makeString ("vcount " )), 1 , & any , false);
4494
4519
is_null_oid = LookupFuncName (list_make1 (makeString ("is_null" )), 1 , & any , false);
4495
4520
4496
4521
for (i = VOPS_CHAR ; i < VOPS_LAST ; i ++ ) {
@@ -4503,21 +4528,25 @@ vops_resolve_functions(void)
4503
4528
4504
4529
static void vops_post_parse_analysis_hook (ParseState * pstate , Query * query )
4505
4530
{
4506
- vops_mutator_context ctx = { NULL ,false} ;
4531
+ vops_var var ;
4507
4532
/* Invoke original hook if needed */
4508
4533
if (post_parse_analyze_hook_next )
4509
4534
{
4510
4535
post_parse_analyze_hook_next (pstate , query );
4511
4536
}
4512
4537
vops_resolve_functions ();
4538
+
4513
4539
filter_mask = ~0 ;
4514
4540
if (query -> commandType == CMD_SELECT &&
4515
4541
vops_auto_substitute_projections &&
4516
4542
pstate -> p_paramref_hook == NULL ) /* do not support prepared statements yet */
4517
4543
{
4518
4544
vops_substitute_tables_with_projections (pstate -> p_sourcetext , query );
4519
4545
}
4520
- (void )query_tree_mutator (query , vops_expression_tree_mutator , & ctx , QTW_DONT_COPY_QUERY );
4546
+ if (is_select_from_vops_projection (query , & var ))
4547
+ {
4548
+ (void )query_tree_mutator (query , vops_expression_tree_mutator , & var , QTW_DONT_COPY_QUERY );
4549
+ }
4521
4550
}
4522
4551
4523
4552
#if PG_VERSION_NUM >=110000
@@ -4547,14 +4576,14 @@ static void vops_explain_hook(Query *query,
4547
4576
{
4548
4577
int cursorOptions = 0 ;
4549
4578
#endif
4579
+ vops_var var ;
4550
4580
PlannedStmt * plan ;
4551
- vops_mutator_context ctx = {NULL ,false};
4552
4581
instr_time planstart , planduration ;
4553
4582
4554
- vops_resolve_functions ();
4555
-
4556
4583
INSTR_TIME_SET_CURRENT (planstart );
4557
4584
4585
+ vops_resolve_functions ();
4586
+
4558
4587
if (query -> commandType == CMD_SELECT &&
4559
4588
vops_auto_substitute_projections &&
4560
4589
params == NULL ) /* do not support prepared statements yet */
@@ -4570,8 +4599,10 @@ static void vops_explain_hook(Query *query,
4570
4599
memset (explain , ' ' , prefix ); /* clear "explain" prefix: we need to preseve node locations */
4571
4600
vops_substitute_tables_with_projections (explain , query );
4572
4601
}
4573
- (void )query_tree_mutator (query , vops_expression_tree_mutator , & ctx , QTW_DONT_COPY_QUERY );
4574
-
4602
+ if (is_select_from_vops_projection (query , & var ))
4603
+ {
4604
+ (void )query_tree_mutator (query , vops_expression_tree_mutator , & var , QTW_DONT_COPY_QUERY );
4605
+ }
4575
4606
plan = pg_plan_query (query , cursorOptions , params );
4576
4607
4577
4608
INSTR_TIME_SET_CURRENT (planduration );
0 commit comments