+ /* Discard cases that have missing values of input variable. */
+ input_pass = i == cmd->n_vars - 1 ? input : casereader_clone (input);
+ input_pass = casereader_create_filter_missing (input_pass, &input_var, 1,
+ cmd->exclude, NULL, NULL);
+
+ /* Keep only the columns we really need, to save time and space when we
+ sort them just below.
+
+ After this projection, the input_pass case indexes look like:
+
+ - 0: input_var.
+ - 1: order_var.
+ - 2 and up: cmd->n_group_vars group variables
+ - 2 + cmd->n_group_vars and up: split variables
+ - 2 + cmd->n_group_vars + n_split_vars: weight var
+ */
+ subcase_init_empty (&projection);
+ subcase_add_var_always (&projection, input_var, SC_ASCEND);
+ subcase_add_var_always (&projection, order_var, SC_ASCEND);
+ subcase_add_vars_always (&projection,
+ cmd->group_vars, cmd->n_group_vars);
+ subcase_add_vars_always (&projection, dict_get_split_vars (d),
+ dict_get_split_cnt (d));
+ if (weight_var != NULL)
+ {
+ subcase_add_var_always (&projection, weight_var, SC_ASCEND);
+ weight_idx = 2 + cmd->n_group_vars + dict_get_split_cnt (d);
+ }
+ else
+ weight_idx = -1;
+ input_pass = casereader_project (input_pass, &projection);
+ subcase_destroy (&projection);
+
+ /* Prepare 'group_vars' as the set of grouping variables. */
+ subcase_init_empty (&group_vars);
+ for (j = 0; j < cmd->n_group_vars; j++)
+ subcase_add_always (&group_vars,
+ j + 2, var_get_width (cmd->group_vars[j]),
+ SC_ASCEND);
+
+ /* Prepare 'rank_ordering' for sorting with the group variables as
+ primary key and the input variable as secondary key. */
+ subcase_clone (&rank_ordering, &group_vars);
+ subcase_add (&rank_ordering, 0, 0, subcase_get_direction (&cmd->sc, i));
+
+ /* Group by split variables */
+ subcase_init_empty (&split_vars);
+ for (j = 0; j < dict_get_split_cnt (d); j++)
+ subcase_add_always (&split_vars, 2 + j + cmd->n_group_vars,
+ var_get_width (dict_get_split_vars (d)[j]),
+ SC_ASCEND);
+ split_grouper = casegrouper_create_subcase (input_pass, &split_vars);
+ subcase_destroy (&split_vars);