protected static function create_sql($parent) {
        global $DB;

        $sql = '';
        $params = [];
        if ($parent->path !== null) {
            // Except for the root element, create the condition that it applies to the context of
            // this element (or anything within it).
            $sql = ' (x.path = ? OR ' . $DB->sql_like('x.path', '?') .')';
            $params[] = $parent->path;
            $params[] = $parent->path . '/%';
            if ($parent->children) {
                // When there are children, these are assumed to have the opposite sign i.e. if we
                // are allowing the parent, we are not allowing the children, and vice versa. So
                // the 'OR' clause for children will be inside this 'AND NOT'.
                $sql .= ' AND NOT (';
            }
        } else if (count($parent->children) > 1) {
            // Place brackets in the query when it is going to be an OR of multiple conditions.
            $sql .= ' (';
        }
        if ($parent->children) {
            $first = true;
            foreach ($parent->children as $child) {
                if ($first) {
                    $first = false;
                } else {
                    $sql  .= ' OR';
                }

                // Recuse to get the child requirements - this will be the check that the context
                // is within the child, plus possibly and 'AND NOT' for any different contexts
                // within the child.
                list ($childsql, $childparams) = self::create_sql($child);
                $sql .= $childsql;
                $params = array_merge($params, $childparams);
            }
            // Close brackets if opened above.
            if ($parent->path !== null || count($parent->children) > 1) {
                $sql .= ')';
            }
        }
        return [$sql, $params];
    }