def _get_custom_queries(self, db, tags, custom_queries, programming_error):
        """
        Given a list of custom_queries, execute each query and parse the result for metrics
        """
        for custom_query in custom_queries:
            metric_prefix = custom_query.get('metric_prefix')
            if not metric_prefix:
                self.log.error("custom query field `metric_prefix` is required")
                continue
            metric_prefix = metric_prefix.rstrip('.')

            query = custom_query.get('query')
            if not query:
                self.log.error("custom query field `query` is required for metric_prefix `{}`".format(metric_prefix))
                continue

            columns = custom_query.get('columns')
            if not columns:
                self.log.error("custom query field `columns` is required for metric_prefix `{}`".format(metric_prefix))
                continue

            cursor = db.cursor()
            with closing(cursor) as cursor:
                try:
                    self.log.debug("Running query: {}".format(query))
                    cursor.execute(query)
                except programming_error as e:
                    self.log.error("Error executing query for metric_prefix {}: {}".format(metric_prefix, str(e)))
                    db.rollback()
                    continue

                for row in cursor:
                    if not row:
                        self.log.debug(
                            "query result for metric_prefix {}: returned an empty result".format(metric_prefix)
                        )
                        continue

                    if len(columns) != len(row):
                        self.log.error(
                            "query result for metric_prefix {}: expected {} columns, got {}".format(
                                metric_prefix, len(columns), len(row)
                            )
                        )
                        continue

                    metric_info = []
                    query_tags = custom_query.get('tags', [])
                    query_tags.extend(tags)

                    for column, value in zip(columns, row):
                        # Columns can be ignored via configuration.
                        if not column:
                            continue

                        name = column.get('name')
                        if not name:
                            self.log.error(
                                "column field `name` is required for metric_prefix `{}`".format(metric_prefix)
                            )
                            break

                        column_type = column.get('type')
                        if not column_type:
                            self.log.error(
                                "column field `type` is required for column `{}` "
                                "of metric_prefix `{}`".format(name, metric_prefix)
                            )
                            break

                        if column_type == 'tag':
                            query_tags.append('{}:{}'.format(name, value))
                        else:
                            if not hasattr(self, column_type):
                                self.log.error(
                                    "invalid submission method `{}` for column `{}` of "
                                    "metric_prefix `{}`".format(column_type, name, metric_prefix)
                                )
                                break
                            try:
                                metric_info.append(('{}.{}'.format(metric_prefix, name), float(value), column_type))
                            except (ValueError, TypeError):
                                self.log.error(
                                    "non-numeric value `{}` for metric column `{}` of "
                                    "metric_prefix `{}`".format(value, name, metric_prefix)
                                )
                                break

                    # Only submit metrics if there were absolutely no errors - all or nothing.
                    else:
                        for info in metric_info:
                            metric, value, method = info
                            getattr(self, method)(metric, value, tags=query_tags)