| 3037 | |
| 3038 | |
| 3039 | static void |
| 3040 | ProcessOrderByStatements(PlannerInfo *root, |
| 3041 | IndexPath *path, int32_t minOrderByColumn, |
| 3042 | int32_t maxOrderByColumn, bool isMultiKeyIndex, |
| 3043 | const char *queryOrderPaths[INDEX_MAX_KEYS], |
| 3044 | bool equalityPrefixes[INDEX_MAX_KEYS], |
| 3045 | bool nonEqualityPrefixes[INDEX_MAX_KEYS], |
| 3046 | int32_t pathSortOrders[INDEX_MAX_KEYS]) |
| 3047 | { |
| 3048 | int i = 0, sortDetailsIndex = 0; |
| 3049 | |
| 3050 | bool hasOrderBy = false; |
| 3051 | bool hasGroupby = false; |
| 3052 | bool isOrderById = false; |
| 3053 | List *sortDetails = GetSortDetails(root, path->path.parent->relid, &hasOrderBy, |
| 3054 | &hasGroupby, &isOrderById); |
| 3055 | |
| 3056 | if (list_length(sortDetails) == 0) |
| 3057 | { |
| 3058 | return; |
| 3059 | } |
| 3060 | |
| 3061 | if (isMultiKeyIndex && hasGroupby) |
| 3062 | { |
| 3063 | /* We can't push down orderby on a multikey index if there is a group by */ |
| 3064 | list_free_deep(sortDetails); |
| 3065 | return; |
| 3066 | } |
| 3067 | |
| 3068 | List *indexOrderBys = NIL; |
| 3069 | List *indexPathKeys = NIL; |
| 3070 | List *indexOrderbyCols = NIL; |
| 3071 | int32_t determinedSortOrder = 0; |
| 3072 | for (; i < minOrderByColumn; i++) |
| 3073 | { |
| 3074 | if (!equalityPrefixes[i]) |
| 3075 | { |
| 3076 | /* No orderby on the column */ |
| 3077 | list_free_deep(sortDetails); |
| 3078 | return; |
| 3079 | } |
| 3080 | } |
| 3081 | |
| 3082 | for (i = minOrderByColumn; i <= maxOrderByColumn; i++) |
| 3083 | { |
| 3084 | if (isMultiKeyIndex) |
| 3085 | { |
| 3086 | /* For a multi-key index, all order by related paths must have no filter specifications */ |
| 3087 | if (nonEqualityPrefixes[i] || equalityPrefixes[i]) |
| 3088 | { |
| 3089 | break; |
| 3090 | } |
| 3091 | } |
| 3092 | |
| 3093 | /* From this point, onwards, each path must either have an order or a valid filter |
| 3094 | * for the path. |
| 3095 | */ |
| 3096 | if (pathSortOrders[i] != 0) |
no test coverage detected