Source: GPUdb.js

/*
 *  This file was autogenerated by the GPUdb schema processor.
 *
 *  DO NOT EDIT DIRECTLY.
 */
/**
 * Creates a GPUdb API object for the specified URL using the given options.
 * Once created, all options are immutable; to use a different URL or change
 * options, create a new instance. (Creating a new instance does not
 * communicate with the server and should not cause performance concerns.)
 *
 * @class
 * @classdesc GPUdb API object that provides access to GPUdb server functions.
 * @param {String|String[]} url The URL of the GPUdb server (e.g.,
                   <code>http://hostname:9191</code>). May also be specified as
                   a list of urls; all urls in the list must be well formed.
 * @param {Object} [options] A set of configurable options for the GPUdb API.
 * @param {String} [options.username] The username to be used for authentication
 *                 to GPUdb. This username will be sent with every GPUdb request
 *                 made via the API along with the specified password and may be
 *                 used for authorization decisions by the server if it is so
 *                 configured. If neither username nor password is specified, no
 *                 authentication will be performed.
 * @param {String} [options.password] The password to be used for authentication
 *                 to GPUdb. This password will be sent with every GPUdb request
 *                 made via the API along with the specified username and may be
 *                 used for authorization decisions by the server if it is so
 *                 configured. If neither username nor password is specified, no
 *                 authentication will be performed.
 * @param {Number} [options.timeout] The timeout value, in milliseconds, after
 *                 which requests to GPUdb will be aborted. A timeout value of
 *                 zero is interpreted as an infinite timeout. Note that timeout
 *                 is not suppored for synchronous requests, which will not
 *                 return until a response is received and cannot be aborted.
 */
function GPUdb(url, options) {
    /**
     * The URLs of the GPUdb servers.
     *
     * @name GPUdb#parsedUrls
     * @type ConnectionToken[]
     * @readonly
     */
	var urls = (url instanceof Array) ? url : [url];
    var parsedUrls = [];

    urls.forEach(function(elem, index, array) {
        var parsed_url = require("url").parse(elem);
        if (parsed_url.protocol !== "http:" && parsed_url.protocol !== "https:") {
            throw new Error("Invalid URL specified.");
        }

        parsedUrls.push(new GPUdb.ConnectionToken(parsed_url));
    });

    var initialIndex = Math.floor(Math.random() * urls.length);
    Object.defineProperty(this, "urls", {
        enumerable: true,
        value: new GPUdb.RingList(parsedUrls, initialIndex)
    });

    /**
     * The URL of the current GPUdb server.
     *
     * @name GPUdb#url
     * @type String
     * @readonly
     */
    Object.defineProperty(this, "url", {
        get: function() {
            var token = this.urls.getCurrentItem();
            return token.protocol + '//' + token.host;
        },
		enumerable: true
	});

    /**
     * The protocol of the current GPUdb server address.
     *
     * @name GPUdb#protocol
     * @type String
     * @readonly
     */
    Object.defineProperty(this, "protocol", {
        get: function() { return this.urls.getCurrentItem().protocol; },
		enumerable: true
	});

    /**
     * The hostname of the current GPUdb server.
     *
     * @name GPUdb#hostname
     * @type String
     * @readonly
     */
    Object.defineProperty(this, "hostname", {
        get: function() { return this.urls.getCurrentItem().hostname; },
		enumerable: true
	});

    /**
     * The port of the current GPUdb server.
     *
     * @name GPUdb#port
     * @type String
     * @readonly
     */
    Object.defineProperty(this, "port", {
        get: function() { return this.urls.getCurrentItem().port; },
		enumerable: true
	});

    /**
     * The pathname of the current GPUdb server.
     *
     * @name GPUdb#pathname
     * @type String
     * @readonly
     */
    Object.defineProperty(this, "pathname", {
        get: function() { return this.urls.getCurrentItem().pathname; },
		enumerable: true
	});

    if (options !== undefined && options !== null) {
        /**
         * The username used for authentication to GPUdb. Will be an empty
         * string if none was provided to the {@link GPUdb GPUdb contructor}.
         *
         * @name GPUdb#username
         * @type String
         * @readonly
         */
        Object.defineProperty(this, "username", {
            enumerable: true,
            value: options.username !== undefined && options.username !== null ? options.username : ""
        });

        /**
         * The password used for authentication to GPUdb. Will be an empty
         * string if none was provided to the {@link GPUdb GPUdb constructor}.
         *
         * @name GPUdb#password
         * @type String
         * @readonly
         */
        Object.defineProperty(this, "password", {
            enumerable: true,
            value: options.password !== undefined && options.password !== null ? options.password : ""
        });

        /**
         * The timeout value, in milliseconds, after which requests to GPUdb
         * will be aborted. A timeout of zero is interpreted as an infinite
         * timeout. Will be zero if none was provided to the {@link GPUdb GPUdb
         * constructor}.
         *
         * @name GPUdb#timeout
         * @type Number
         * @readonly
         */
        Object.defineProperty(this, "timeout", {
            enumerable: true,
            value: options.timeout !== undefined && options.timeout !== null && options.timeout >= 0 ? options.timeout : 0
        });

        /**
         * Function to get request cookie
         *
         * @name GPUdb#getCookie
         * @type Function
         * @readonly
         */
        Object.defineProperty(this, "getCookie", {
            enumerable: true,
            value: options.getCookie
        });

        /**
         * Function to set responce cookie
         *
         * @name GPUdb#setCookie
         * @type Function
         * @readonly
         */
        Object.defineProperty(this, "setCookie", {
            enumerable: true,
            value: options.setCookie
        });

    } else {
        Object.defineProperty( this, "username", { enumerable: true, value: "" } );
        Object.defineProperty( this, "password", { enumerable: true, value: "" } );
        Object.defineProperty( this, "timeout", { enumerable: true, value: 0 } );
    }

    if (this.username !== "" || this.password !== "") {
        Object.defineProperty(this, "authorization", {
            value: "Basic " + new Buffer(this.username + ":" + this.password).toString("base64")
        });
    } else {
        Object.defineProperty(this, "authorization", { value: "" });
    }


    // Set the default value of the GPUdb#force_infinity_nan_conversion_to_null property
    this._force_infinity_nan_conversion_to_null = false;

    /*
     * The flag to indicate if quoted "Infinity", "-Infinity", and "NaN"
     * values returned by Kinetica will be converted to null.  Regular
     * Infinity, -Infinity, and NaN are automatically handled; but
     * the quoted versions need special handling that is an expensive
     * operation.  Default is false.
     *
     * @name GPUdb#force_infinity_nan_conversion_to_null
     * @type Boolean
     * @readonly
     */
    Object.defineProperty( this, "force_infinity_nan_conversion_to_null",
                           {
                               enumerable: true,
                               get: function() { return this._force_infinity_nan_conversion_to_null; },
                               set: function( newValue ) {
                                   // Value must be boolean
                                   if ( [true, false].indexOf( newValue ) == -1 ) {
                                       throw "Value must be true or false"; }

                                   // Only allow setting a boolean value
                                   this._force_infinity_nan_conversion_to_null = Boolean( newValue );
                               }
                           } );

}


module.exports = GPUdb;

/**
 * Wrapper struct to tie together the parsed url fields.
 * @private
 */
GPUdb.ConnectionToken = function(parsed_url) {
    Object.defineProperty(this, "protocol", { value: parsed_url.protocol });
    Object.defineProperty(this, "hostname", { value: parsed_url.hostname });
    Object.defineProperty(this, "port", { value: parsed_url.port });
    Object.defineProperty(this, "pathname", { value: parsed_url.pathname.replace(/\/$/, "") });
    Object.defineProperty(this, "host", { value: parsed_url.host });
}

/**
 * Equality helper for comparing instances.
 * @private
 * @param {ConnectionToken} other The instance to compare to.
 */
GPUdb.ConnectionToken.prototype.equals = function(other) {
    return this.host === other.host;
}

/**
 * Submits an arbitrary request to GPUdb. The response will be returned via the
 * specified callback function, or via a promise if no callback function is
 * provided.
 *
 * @param {String} endpoint The endpoint to which to submit the request.
 * @param {Object} request The request object to submit.
 * @param {GPUdbCallback} [callback] The callback function.
 * @returns {Promise} A promise that will be fulfilled with the response object,
 *                    if no callback function is provided.
 */
GPUdb.prototype.submit_request = function(endpoint, request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self.submit_request(endpoint, request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

    var requestString = JSON.stringify(request);
    var initialConnToken = this.urls.getCurrentItem();
    var failureCount = 0;
    var timeout = this.timeout;
    var urls = this.urls;
    var authorization = this.authorization;
    var getCookie = this.getCookie;
    var setCookie = this.setCookie;

	/// Wraps the async callback with auto-retry logic
    var failureWrapperCB = function(err, data, url) {
        failureCount += 1;
        if (failureCount < urls.getSize()) {
            // If the current item has changed another request failed and
            // has already advanced the list. Retry using the new head.
            if ((url !== urls.getCurrentItem()) ||
                (!urls.getNextItem().equals(initialConnToken))) {
                sendRequest();
            }
        }
        else {
            callback(err, data);
        }
    };

	var sendRequest = function() {
        var connToken = urls.getCurrentItem();

        if (connToken.protocol === "http:") {
            var http = require("http");
        } else {
            var http = require("https");
        }

        var headers = { "Content-type": "application/json" };

        if (authorization !== "") {
            headers["Authorization"] = authorization;
        }

        if (getCookie && typeof getCookie === "function") {
            headers["Cookie"] = getCookie();
        }
        var got_error = false;

        var req = http.request({
                hostname: connToken.hostname,
                port: connToken.port,
                path: connToken.pathname + endpoint,
                method: "POST",
                headers: headers
            }, function(res) {
                var responseString = "";
                if (setCookie && typeof setCookie === "function") {
                    setCookie(res.headers["set-cookie"]);
                }

                res.on("data", function(chunk) {
                    responseString += chunk;
                });

                res.on("end", function() {
                    if (got_error) {
                        return;
                    }

                    try {
                        var response = JSON.parse(responseString);
                    } catch (e) {
                        callback(new Error("Unable to parse response: " + e), null);
                        return;
                    }

                    if (response.status === "OK") {
                        try {
                            var data = JSON.parse(response.data_str.replace(/\\U/g,"\\u"));
                        } catch (e) {
                            callback(new Error("Unable to parse response: " + e), null);
                            return;
                        }

                        if ("x-request-time-secs" in res.headers) {
                            data.request_time_secs = Number(res.headers["x-request-time-secs"]);
                        }

                        callback(null, data);
                    } else {
                        callback(new Error(response.message), null);
                    }
                });

                res.on("error", function(err) {
                    got_error = true;
                    failureWrapperCB(new Error(), null, connToken);
                });
            });

        req.on("error", function(err) {
            got_error = true;
            failureWrapperCB(new Error(), null, connToken);
        });

        req.setTimeout(timeout, function() {
            got_error = true;
            failureWrapperCB(new Error("Request timed out"), null, connToken);
        });

        req.write(requestString);
        req.end();
    };

    sendRequest();
};

/**
 * Request a WMS (Web Map Service) rasterized image. The image will be returned
 * as a Node.js Buffer object via the specified callback function, or via a
 * promise if no callback function is provided.
 *
 * @param {Object} request Object containing WMS parameters.
 * @param {GPUdbCallback} [callback] The callback function.
 * @returns {Promise} A promise that will be fulfilled with the image, if no
 *                    callback function is provided.
 */
GPUdb.prototype.wms_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self.wms_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

    var queryString = require("querystring").stringify(request);
    var initialConnToken = this.urls.getCurrentItem();
    var failureCount = 0;
    var timeout = this.timeout;
    var urls = this.urls;
    var authorization = this.authorization;
    var getCookie = this.getCookie;
    var setCookie = this.setCookie;

	/// Wraps the async callback with auto-retry logic
    var failureWrapperCB = function(err, data, url) {
        failureCount += 1;
        if (failureCount < urls.getSize()) {
            // If the current item has changed another request failed and
            // has already advanced the list. Retry using the new head.
            if ((url !== urls.getCurrentItem()) ||
                (!urls.getNextItem().equals(initialConnToken))) {
                sendRequest();
            }
        }
        else {
            callback(err, data);
        }
    };

    var sendRequest = function() {
        var connToken = urls.getCurrentItem();

        if (connToken.protocol === "http:") {
            var http = require("http");
        } else {
            var http = require("https");
        }

        var headers = { "Content-type": "application/json" };

        if (authorization !== "") {
            headers["Authorization"] = authorization;
        }

        if (getCookie && typeof getCookie === "function") {
            headers["Cookie"] = getCookie();
        }
        var got_error = false;

        var req = http.request({
            hostname: connToken.hostname,
            port: connToken.port,
            path: connToken.pathname + "/wms?" + queryString,
            headers: headers,
        }, function(res) {
            var data = [];
            if (setCookie && typeof setCookie === "function") {
                setCookie(res.headers["set-cookie"]);
            }

            res.on("data", function(chunk) {
                data.push(chunk);
            });

            res.on("end", function() {
                if (got_error) {
                    return;
                }

                result = Buffer.concat(data);

                if ("x-request-time-secs" in res.headers) {
                    result.request_time_secs = Number(res.headers["x-request-time-secs"]);
                }

                callback(null, result);
            });

            res.on("error", function(err) {
                got_error = true;
                failureWrapperCB(err, null, connToken);
            });
        });

        req.on("error", function(err) {
            got_error = true;
            failureWrapperCB(err, null, connToken);
        });

        req.setTimeout(timeout, function() {
            got_error = true;
            failureWrapperCB(new Error("Request timed out"), null, connToken);
        });

        req.end();
    };

    sendRequest();
}
/**
 * A list with only one exposed element at a time, but with N stored elements.
 * The elements of the list are immutable.
 * @private
 */
GPUdb.RingList = function(items, initialIndex) {
    Object.defineProperty(this, "items", { enumerable: true, value: items });
    Object.defineProperty(this, "index", {
        enumerable: true,
        value: (initialIndex !== undefined && initialIndex !== null &&
                initialIndex >= 0 ? initialIndex : 0),
        writable: true
    });
}

/**
 * @private
 * @return The currently exposed item
 */
GPUdb.RingList.prototype.getCurrentItem = function() {
    return this.items[this.index];
}

/**
 * Increments the current item index, wrapping if necessary.
 * @private
 * @return The currently exposed item
 */
GPUdb.RingList.prototype.getNextItem = function() {
    this.index += 1;
    if (this.index >= this.items.length) {
        this.index = 0;
    }

    return this.items[this.index];
}

/**
 * @private
 *
 * @return The number of elements available within the list.
 */
GPUdb.RingList.prototype.getSize = function() {
    return this.items.length;
}

/**
 * Callback function used for asynchronous GPUdb calls.
 *
 * @callback GPUdbCallback
 * @param {Error} err Object containing error information returned from the
 *                call. Will be null if no error occurred.
 * @param {Object} response Object containing any data returned from the call.
 *                 Will be null if an error occurred.
 */
/**
 * Creates a Type object containing metadata about a GPUdb type.
 *
 * @class
 * @classdesc Metadata about a GPUdb type.
 * @param {String} label A user-defined description string which can be used to
 *                 differentiate between data with otherwise identical schemas.
 * @param {...GPUdb.Type.Column} columns The list of columns that the type
 *                               comprises.
 */
GPUdb.Type = function(label, columns) {
    /**
     * A user-defined description string which can be used to differentiate
     * between data with otherwise identical schemas.
     *
     * @name GPUdb.Type#label
     * @type String
     */
    this.label = label;

    /**
     * The list of columns that the type comprises.
     *
     * @name GPUdb.Type#columns
     * @type GPUdb.Type.Column[]
     */
    if (Array.isArray(columns)) {
        this.columns = columns;
    } else {
        this.columns = [];

        for (var i = 1; i < arguments.length; i++) {
            this.columns.push(arguments[i]);
        }
    }
};

/**
 * Creates a Column object containing metadata about a column that is part of a
 * GPUdb type.
 *
 * @class
 * @classdesc Metadata about a column that is part of a GPUdb type.
 * @param {String} name The name of the column.
 * @param {String} type The data type of the column.
 * @param {...String} [properties] The list of properties that apply to the
                      column; defaults to none.
 */
GPUdb.Type.Column = function(name, type, properties) {
    /**
     * The name of the column.
     *
     * @name GPUdb.Type.Column#name
     * @type String
     */
    this.name = name;

    /**
     * The data type of the column.
     *
     * @name GPUdb.Type.Column#type
     * @type String
     */
    this.type = type;

    /**
     * The list of properties that apply to the column.
     *
     * @name GPUdb.Type.Column#properties
     * @type String[]
     */
    if (properties !== undefined && properties !== null) {
        if (Array.isArray(properties)) {
            this.properties = properties;
        } else {
            this.properties = [];

            for (var i = 2; i < arguments.length; i++) {
                this.properties.push(arguments[i]);
            }
        }
    } else {
        this.properties = [];
    }
};

/**
 * Gets whether the column is nullable.
 *
 * @returns {boolean} Whether the column is nullable.
 */
GPUdb.Type.Column.prototype.is_nullable = function() {
    return this.properties.indexOf("nullable") > -1;
};

/**
 * Creates a Type object using data returned from the GPUdb show_table or
 * show_types endpoints.
 *
 * @param {String} label A user-defined description string which can be used to
 *                 differentiate between data with otherwise identical schemas.
 * @param {String|Object} type_schema The Avro record schema for the type.
 * @param {Object.<String, String[]>} properties A map of column names to
 *                                    lists of properties that apply to those
 *                                    columns.
 * @returns {GPUdb.Type} The Type object.
 */
GPUdb.Type.from_type_info = function(label, type_schema, properties) {
    if (typeof type_schema === "string" || type_schema instanceof String) {
        type_schema = JSON.parse(type_schema);
    }

    var columns = [];

    for (var i = 0; i < type_schema.fields.length; i++) {
        var field = type_schema.fields[i];
        var type = field.type;

        if (Array.isArray(type)) {
            for (var j = 0; j < type.length; j++) {
                if (type[j] !== "null") {
                    type = type[j];
                    break;
                }
            }
        }

        columns.push(new GPUdb.Type.Column(field.name, type, properties[field.name]));
    }

    return new GPUdb.Type(label, columns);
};

/**
 * Generates an Avro record schema based on the metadata in the Type object.
 *
 * @returns {Object} The Avro record schema.
 */
GPUdb.Type.prototype.generate_schema = function() {
    var schema = {
        type: "record",
        name: "type_name",
        fields: []
    };

    for (var i = 0; i < this.columns.length; i++) {
        var column = this.columns[i];

        schema.fields.push({
            name: column.name,
            type: column.is_nullable() ? [ column.type, "null" ] : column.type
        });
    }

    return schema;
};

/**
 * The version number of the GPUdb JavaScript API.
 *
 * @name GPUdb#api_version
 * @type String
 * @readonly
 * @static
 */
Object.defineProperty(GPUdb, "api_version", { enumerable: true, value: "6.2.0.1" });

/**
 * Constant used with certain requests to indicate that the maximum allowed
 * number of results should be returned.
 *
 * @name GPUdb#END_OF_SET
 * @type Number
 * @readonly
 * @static
 */
Object.defineProperty(GPUdb, "END_OF_SET", { value: -9999 });


/**
 * Decodes a JSON string, or array of JSON strings, returned from GPUdb into
 * JSON object(s).
 *
 * @param {String | String[]} o The JSON string(s) to decode.
 * @returns {Object | Object[]} The decoded JSON object(s).
 */
GPUdb.decode = function(o) {
    if (Array.isArray(o)) {
        var result = [];

        for (var i = 0; i < o.length; i++) {
            result.push(GPUdb.decode(o[i]));
        }

        return result;
    } else {
        return JSON.parse(o);
    }
};



/**
 * Decodes a JSON string, or array of JSON strings, returned from GPUdb into
 * JSON object(s).
 *
 * @param {String | String[]} o The JSON string(s) to decode.
 * @returns {Object | Object[]} The decoded JSON object(s).
 */
GPUdb.prototype.decode = function(o) {
    // Force quoted "Infinity", "-Infinity", and "NaN" to be converted
    // to null
    if ( this.force_infinity_nan_conversion_to_null === true ) {
        return GPUdb.decode_no_inf_nan( o );
    }

    // Regular conversion, no special transformation needed
    return GPUdb.decode_regular( o );
};


/**
 * Decodes a JSON string, or array of JSON strings, returned from GPUdb into
 * JSON object(s).
 *
 * @param {String | String[]} o The JSON string(s) to decode.
 * @returns {Object | Object[]} The decoded JSON object(s).
 */
GPUdb.decode_regular = function(o) {
    if (Array.isArray(o)) {
        var result = [];

        for (var i = 0; i < o.length; i++) {
            result.push( GPUdb.decode_regular(o[i]) );
        }

        return result;
    } else {
        return JSON.parse(o);
    }
};
    

/**
 * Decodes a JSON string, or array of JSON strings, returned from GPUdb into
 * JSON object(s).  Special treatment for quoted "Infinity", "-Infinity",
 * and "NaN".  Catches those and converts to null.  This is significantly
 * slower than the regular decode function.
 *
 * @param {String | String[]} o The JSON string(s) to decode.
 * @returns {Object | Object[]} The decoded JSON object(s).
 */
GPUdb.decode_no_inf_nan = function(o) {
    if (Array.isArray(o)) {
        var result = [];

        for (var i = 0; i < o.length; i++) {
            result.push( GPUdb.decode_no_inf_nan( o[i] ) );
        }

        return result;
    } else {
        // Check for 
        return JSON.parse( o, function(k, v) {
            if (v === "Infinity") return null;
            else if (v === "-Infinity") return null;
            else if (v === "NaN") return null;
            else return v;
        } );
    }
};


/**
 * Encodes a JSON object, or array of JSON objects, into JSON string(s) to be
 * passed to GPUdb.
 *
 * @param {Object | Object[]} o The JSON object(s) to encode.
 * @returns {String | String[]} The encoded JSON string(s).
 */
GPUdb.encode = function(o) {
    if (Array.isArray(o)) {
        var result = [];

        for (var i = 0; i < o.length; i++) {
            result.push(GPUdb.encode(o[i]));
        }

        return result;
    } else {
        return JSON.stringify(o);
    }
};
/**
 * Creates a Type object containing metadata about the type stored in the
 * specified table in GPUdb and returns it via the specified callback function,
 * or via a promise if no callback function is provided.
 *
 * @param {GPUdb} gpudb GPUdb API object.
 * @param {String} table_name The table from which to obtain type metadata.
 * @param {GPUdbCallback} [callback] The callback function.
 * @returns {Promise} A promise that will be fulfilled with the type object, if
 *                    no callback function is provided.
 */
GPUdb.Type.from_table = function(gpudb, table_name, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self.from_table(gpudb, table_name, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

    var process_response = function(response, callback) {
        if (response.type_ids.length === 0) {
            callback(new Error("Table " + table_name + " does not exist."), null);
        }

        if (response.type_ids.length > 1) {
            var type_id = response.type_ids[0];

            for (var i = 1; i < response.type_ids.length; i++) {
                if (response.type_ids[i] !== type_id) {
                    callback(new Error("Table " + table_name + " is not homogeneous."), null);
                }
            }
        }

        callback(null, GPUdb.Type.from_type_info(response.type_labels[0], response.type_schemas[0], response.properties[0]));
    };

    gpudb.show_table(table_name, {}, function(err, data) {
        if (err === null) {
            process_response(data, callback);
        } else {
            callback(err, null);
        }
    });
};

/**
 * Creates a Type object containing metadata about the specified type in GPUdb
 * and returns it via the specified callback function, or via a promise if no
 * callback function is provided.
 *
 * @param {GPUdb} gpudb GPUdb API object.
 * @param {String} type_id The type for which to obtain metadata.
 * @param {GPUdbCallback} [callback] The callback function.
 * @returns {Promise} A promise that will be fulfilled with the type object, if
 *                    no callback function is provided.
 */
GPUdb.Type.from_type = function(gpudb, type_id, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self.from_type(gpudb, type_id, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

    var process_response = function(response, callback) {
        if (response.type_ids.length === 0) {
            callback(Error("Type " + type_id + " does not exist."), null);
        }

        callback(null, GPUdb.Type.from_type_info(response.labels[0], response.type_schemas[0], response.properties[0]));
    };

    gpudb.show_types(type_id, "", {}, function(err, data) {
        if (err === null) {
            process_response(data, callback);
        } else {
            callback(err, null);
        }
    });
};

/**
 * Creates a new type in GPUdb based on the metadata in the Type object and
 * returns the GPUdb type ID via the specified callback function, or via a
 * promise if no callback function is provided, for use in subsequent
 * operations.
 *
 * @param {GPUdb} gpudb GPUdb API object.
 * @param {GPUdbCallback} [callback] The callback function.
 * @returns {Promise} A promise that will be fulfilled with the type ID, if no
 *                    callback function is provided.
 */
GPUdb.Type.prototype.create = function(gpudb, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self.create(gpudb, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

    var properties = {};

    for (var i = 0; i < this.columns.length; i++) {
        var column = this.columns[i];

        if (column.properties.length > 0) {
            properties[column.name] = column.properties;
        }
    }

    gpudb.create_type(JSON.stringify(this.generate_schema()), this.label, properties, {}, function(err, data) {
        if (err === null) {
            callback(null, data.type_id);
        } else {
            callback(err, null);
        }
    });
};


/**
 * Retrieves records from a given table as a GeoJSON, optionally filtered by an expression
 * and/or sorted by a column. This operation can be performed on tables, views,
 * or on homogeneous collections (collections containing tables of all the same
 * type). Records can be returned encoded as binary, json or geojson.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters. Note that when paging through a table, if
 * the table (or the underlying table in case of a view) is updated (records
 * are inserted, deleted or modified) the records retrieved may differ between
 * calls based on the updates applied.
 *
 * @param {String} table_name  Name of the table from which the records will be
 *                             fetched. Must be a table, view or homogeneous
 *                             collection.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned. Or END_OF_SET (-9999) to
 *                        indicate that the max number of results should be
 *                        returned.
 * @param {Object} options
 *                          <ul>
 *                                  <li> 'expression': Optional filter
 *                          expression to apply to the table.
 *                                  <li> 'fast_index_lookup': Indicates if
 *                          indexes should be used to perform the lookup for a
 *                          given expression if possible. Only applicable if
 *                          there is no sorting, the expression contains only
 *                          equivalence comparisons based on existing tables
 *                          indexes and the range of requested values is from
 *                          [0 to END_OF_SET].
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'sort_by': Optional column that the
 *                          data should be sorted by. Empty by default (i.e. no
 *                          sorting is applied).
 *                                  <li> 'sort_order': String indicating how
 *                          the returned values should be sorted - ascending or
 *                          descending. If sort_order is provided, sort_by has
 *                          to be provided.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'ascending'
 *                                  <li> 'descending'
 *                          </ul>
 *                          The default value is 'ascending'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the GeoJSON
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_geo_json = function(table_name, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_geo_json(table_name, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        offset: (offset !== undefined && offset !== null) ? offset : 0,
        limit: (limit !== undefined && limit !== null) ? limit : 10000,
        encoding: "geojson",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/get/records", actual_request, function(err, data) {
        if (err === null) {
            var geo_json = GPUdb.decode( data.records_json )[0];
            // Return just the GeoJSON
            callback(err, geo_json);
        }
        else {
            // There was an error, so nothing to decode
            callback(err, data);
        }
    });
};



/**
 * Perform the requested action on a list of one or more job(s). Based on the
 * type of job and the current state of execution, the action may not be
 * successfully executed. The final result of the attempted actions for each
 * specified job is returned in the status array of the response. See <a
 * href="../../gpudbAdmin/job_manager.html" target="_top">Job Manager</a> for
 * more information.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_alter_jobs_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_alter_jobs_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        job_ids: request.job_ids,
        action: request.action,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/alter/jobs", actual_request, callback);
};

/**
 * Perform the requested action on a list of one or more job(s). Based on the
 * type of job and the current state of execution, the action may not be
 * successfully executed. The final result of the attempted actions for each
 * specified job is returned in the status array of the response. See <a
 * href="../../gpudbAdmin/job_manager.html" target="_top">Job Manager</a> for
 * more information.
 *
 * @param {Number[]} job_ids  Jobs to be modified.
 * @param {String} action  Action to be performed on the jobs specified by
 *                         job_ids.
 *                         Supported values:
 *                         <ul>
 *                                 <li> 'cancel'
 *                         </ul>
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_alter_jobs = function(job_ids, action, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_alter_jobs(job_ids, action, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        job_ids: job_ids,
        action: action,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/alter/jobs", actual_request, callback);
};

/**
 * Take the system offline. When the system is offline, no user operations can
 * be performed with the exception of a system shutdown.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_offline_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_offline_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        offline: request.offline,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/offline", actual_request, callback);
};

/**
 * Take the system offline. When the system is offline, no user operations can
 * be performed with the exception of a system shutdown.
 *
 * @param {Boolean} offline  Set to true if desired state is offline.
 *                           Supported values:
 *                           <ul>
 *                                   <li> true
 *                                   <li> false
 *                           </ul>
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'flush_to_disk': Flush to disk when
 *                          going offline
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_offline = function(offline, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_offline(offline, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        offline: offline,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/offline", actual_request, callback);
};

/**
 * Retrieves a list of the most recent alerts generated.  The number of alerts
 * to retrieve is specified in this request.
 * Returns lists of alert data, earliest to latest
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_alerts_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_alerts_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        num_alerts: request.num_alerts,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/show/alerts", actual_request, callback);
};

/**
 * Retrieves a list of the most recent alerts generated.  The number of alerts
 * to retrieve is specified in this request.
 * Returns lists of alert data, earliest to latest
 *
 * @param {Number} num_alerts  Number of most recent alerts to request. The
 *                             response will return <code>num_alerts</code>
 *                             alerts, or less if there are less in the system.
 *                             A value of 0 returns all stored alerts.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_alerts = function(num_alerts, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_alerts(num_alerts, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        num_alerts: num_alerts,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/show/alerts", actual_request, callback);
};

/**
 * Get a list of the current jobs in GPUdb.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_jobs_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_jobs_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/show/jobs", actual_request, callback);
};

/**
 * Get a list of the current jobs in GPUdb.
 *
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'show_details':
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_jobs = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_jobs(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/show/jobs", actual_request, callback);
};

/**
 * Show the mapping of shards to the corresponding rank and tom.  The response
 * message contains list of 16384 (total number of shards in the system) Rank
 * and TOM numbers corresponding to each shard.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_shards_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_shards_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/show/shards", actual_request, callback);
};

/**
 * Show the mapping of shards to the corresponding rank and tom.  The response
 * message contains list of 16384 (total number of shards in the system) Rank
 * and TOM numbers corresponding to each shard.
 *
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_show_shards = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_show_shards(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/show/shards", actual_request, callback);
};

/**
 * Exits the database server application.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_shutdown_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_shutdown_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        exit_type: request.exit_type,
        authorization: request.authorization,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/shutdown", actual_request, callback);
};

/**
 * Exits the database server application.
 *
 * @param {String} exit_type  Reserved for future use. User can pass an empty
 *                            string.
 * @param {String} authorization  No longer used. User can pass an empty
 *                                string.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_shutdown = function(exit_type, authorization, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_shutdown(exit_type, authorization, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        exit_type: exit_type,
        authorization: authorization,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/shutdown", actual_request, callback);
};

/**
 * Verify database is in a consistent state.  When inconsistencies or errors
 * are found, the verified_ok flag in the response is set to false and the list
 * of errors found is provided in the error_list.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_verify_db_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_verify_db_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/admin/verifydb", actual_request, callback);
};

/**
 * Verify database is in a consistent state.  When inconsistencies or errors
 * are found, the verified_ok flag in the response is set to false and the list
 * of errors found is provided in the error_list.
 *
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'rebuild_on_error':
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'verify_persist':
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.admin_verify_db = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_verify_db(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/admin/verifydb", actual_request, callback);
};

/**
 * Calculates and returns the convex hull for the values in a table specified
 * by <code>table_name</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_convex_hull_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_convex_hull_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/convexhull", actual_request, callback);
};

/**
 * Calculates and returns the convex hull for the values in a table specified
 * by <code>table_name</code>.
 *
 * @param {String} table_name  Name of table on which the operation will be
 *                             performed. Must be an existing table.  It cannot
 *                             be a collection.
 * @param {String} x_column_name  Name of the column containing the x
 *                                coordinates of the points for the operation
 *                                being performed.
 * @param {String} y_column_name  Name of the column containing the y
 *                                coordinates of the points for the operation
 *                                being performed.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_convex_hull = function(table_name, x_column_name, y_column_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_convex_hull(table_name, x_column_name, y_column_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/convexhull", actual_request, callback);
};

/**
 * Calculates unique combinations (groups) of values for the given columns in a
 * given table/view/collection and computes aggregates on each unique
 * combination. This is somewhat analogous to an SQL-style SELECT...GROUP BY.
 * <p>
 * For aggregation details and examples, see <a
 * href="../../concepts/aggregation.html" target="_top">Aggregation</a>.  For
 * limitations, see <a href="../../concepts/aggregation.html#limitations"
 * target="_top">Aggregation Limitations</a>.
 * <p>
 * Any column(s) can be grouped on, and all column types except
 * unrestricted-length strings may be used for computing applicable aggregates;
 * columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a> are unable to be used in grouping or
 * aggregation.
 * <p>
 * The results can be paged via the <code>offset</code> and <code>limit</code>
 * parameters. For example, to get 10 groups with the largest counts the inputs
 * would be: limit=10, options={"sort_order":"descending", "sort_by":"value"}.
 * <p>
 * <code>options</code> can be used to customize behavior of this call e.g.
 * filtering or sorting the results.
 * <p>
 * To group by columns 'x' and 'y' and compute the number of objects within
 * each group, use:  column_names=['x','y','count(*)'].
 * <p>
 * To also compute the sum of 'z' over each group, use:
 * column_names=['x','y','count(*)','sum(z)'].
 * <p>
 * Available <a href="../../concepts/expressions.html#aggregate-expressions"
 * target="_top">aggregation functions</a> are: count(*), sum, min, max, avg,
 * mean, stddev, stddev_pop, stddev_samp, var, var_pop, var_samp, arg_min,
 * arg_max and count_distinct.
 * <p>
 * Available grouping functions are <a href="../../concepts/rollup.html"
 * target="_top">Rollup</a>, <a href="../../concepts/cube.html"
 * target="_top">Cube</a>, and <a href="../../concepts/grouping_sets.html"
 * target="_top">Grouping Sets</a>
 * <p>
 * This service also provides support for <a href="../../concepts/pivot.html"
 * target="_top">Pivot</a> operations.
 * <p>
 * Filtering on aggregates is supported via expressions using <a
 * href="../../concepts/expressions.html#aggregate-expressions"
 * target="_top">aggregation functions</a> supplied to <code>having</code>.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 * <p>
 * If a <code>result_table</code> name is specified in the
 * <code>options</code>, the results are stored in a new table with that
 * name--no results are returned in the response.  Both the table name and
 * resulting column names must adhere to <a
 * href="../../concepts/tables.html#table" target="_top">standard naming
 * conventions</a>; column/aggregation expressions will need to be aliased.  If
 * the source table's <a href="../../concepts/tables.html#shard-keys"
 * target="_top">shard key</a> is used as the grouping column(s) and all result
 * records are selected (<code>offset</code> is 0 and <code>limit</code> is
 * -9999), the result table will be sharded, in all other cases it will be
 * replicated.  Sorting will properly function only if the result table is
 * replicated or if there is only one processing node and should not be relied
 * upon in other cases.  Not available when any of the values of
 * <code>column_names</code> is an unrestricted-length string.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_group_by_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_group_by_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_names: request.column_names,
        offset: request.offset,
        limit: (request.limit !== undefined && request.limit !== null) ? request.limit : 1000,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/aggregate/groupby", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Calculates unique combinations (groups) of values for the given columns in a
 * given table/view/collection and computes aggregates on each unique
 * combination. This is somewhat analogous to an SQL-style SELECT...GROUP BY.
 * <p>
 * For aggregation details and examples, see <a
 * href="../../concepts/aggregation.html" target="_top">Aggregation</a>.  For
 * limitations, see <a href="../../concepts/aggregation.html#limitations"
 * target="_top">Aggregation Limitations</a>.
 * <p>
 * Any column(s) can be grouped on, and all column types except
 * unrestricted-length strings may be used for computing applicable aggregates;
 * columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a> are unable to be used in grouping or
 * aggregation.
 * <p>
 * The results can be paged via the <code>offset</code> and <code>limit</code>
 * parameters. For example, to get 10 groups with the largest counts the inputs
 * would be: limit=10, options={"sort_order":"descending", "sort_by":"value"}.
 * <p>
 * <code>options</code> can be used to customize behavior of this call e.g.
 * filtering or sorting the results.
 * <p>
 * To group by columns 'x' and 'y' and compute the number of objects within
 * each group, use:  column_names=['x','y','count(*)'].
 * <p>
 * To also compute the sum of 'z' over each group, use:
 * column_names=['x','y','count(*)','sum(z)'].
 * <p>
 * Available <a href="../../concepts/expressions.html#aggregate-expressions"
 * target="_top">aggregation functions</a> are: count(*), sum, min, max, avg,
 * mean, stddev, stddev_pop, stddev_samp, var, var_pop, var_samp, arg_min,
 * arg_max and count_distinct.
 * <p>
 * Available grouping functions are <a href="../../concepts/rollup.html"
 * target="_top">Rollup</a>, <a href="../../concepts/cube.html"
 * target="_top">Cube</a>, and <a href="../../concepts/grouping_sets.html"
 * target="_top">Grouping Sets</a>
 * <p>
 * This service also provides support for <a href="../../concepts/pivot.html"
 * target="_top">Pivot</a> operations.
 * <p>
 * Filtering on aggregates is supported via expressions using <a
 * href="../../concepts/expressions.html#aggregate-expressions"
 * target="_top">aggregation functions</a> supplied to <code>having</code>.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 * <p>
 * If a <code>result_table</code> name is specified in the
 * <code>options</code>, the results are stored in a new table with that
 * name--no results are returned in the response.  Both the table name and
 * resulting column names must adhere to <a
 * href="../../concepts/tables.html#table" target="_top">standard naming
 * conventions</a>; column/aggregation expressions will need to be aliased.  If
 * the source table's <a href="../../concepts/tables.html#shard-keys"
 * target="_top">shard key</a> is used as the grouping column(s) and all result
 * records are selected (<code>offset</code> is 0 and <code>limit</code> is
 * -9999), the result table will be sharded, in all other cases it will be
 * replicated.  Sorting will properly function only if the result table is
 * replicated or if there is only one processing node and should not be relied
 * upon in other cases.  Not available when any of the values of
 * <code>column_names</code> is an unrestricted-length string.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing
 *                             table/view/collection.
 * @param {String[]} column_names  List of one or more column names,
 *                                 expressions, and aggregate expressions.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned Or END_OF_SET (-9999) to
 *                        indicate that the max number of results should be
 *                        returned.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the table specified
 *                          in <code>result_table</code>. If the collection
 *                          provided is non-existent, the collection will be
 *                          automatically created. If empty, then the table
 *                          will be a top-level table.  Additionally this
 *                          option is invalid if <code>table_name</code> is a
 *                          collection.
 *                                  <li> 'expression': Filter expression to
 *                          apply to the table prior to computing the aggregate
 *                          group by.
 *                                  <li> 'having': Filter expression to apply
 *                          to the aggregated results.
 *                                  <li> 'sort_order': String indicating how
 *                          the returned values should be sorted - ascending or
 *                          descending.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'ascending': Indicates that the
 *                          returned values should be sorted in ascending
 *                          order.
 *                                  <li> 'descending': Indicates that the
 *                          returned values should be sorted in descending
 *                          order.
 *                          </ul>
 *                          The default value is 'ascending'.
 *                                  <li> 'sort_by': String determining how the
 *                          results are sorted.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'key': Indicates that the returned
 *                          values should be sorted by key, which corresponds
 *                          to the grouping columns. If you have multiple
 *                          grouping columns (and are sorting by key), it will
 *                          first sort the first grouping column, then the
 *                          second grouping column, etc.
 *                                  <li> 'value': Indicates that the returned
 *                          values should be sorted by value, which corresponds
 *                          to the aggregates. If you have multiple aggregates
 *                          (and are sorting by value), it will first sort by
 *                          the first aggregate, then the second aggregate,
 *                          etc.
 *                          </ul>
 *                          The default value is 'value'.
 *                                  <li> 'result_table': The name of the table
 *                          used to store the results. Has the same naming
 *                          restrictions as <a
 *                          href="../../concepts/tables.html"
 *                          target="_top">tables</a>. Column names (group-by
 *                          and aggregate fields) need to be given aliases e.g.
 *                          ["FChar256 as fchar256", "sum(FDouble) as sfd"].
 *                          If present, no results are returned in the
 *                          response.  This option is not available if one of
 *                          the grouping attributes is an unrestricted string
 *                          (i.e.; not charN) type.
 *                                  <li> 'result_table_persist': If
 *                          <code>true</code>, then the result table specified
 *                          in <code>result_table</code> will be persisted and
 *                          will not expire unless a <code>ttl</code> is
 *                          specified.   If <code>false</code>, then the result
 *                          table will be an in-memory table and will expire
 *                          unless a <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'result_table_force_replicated': Force
 *                          the result table to be replicated (ignores any
 *                          sharding). Must be used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'result_table_generate_pk': If 'true'
 *                          then set a primary key for the result table. Must
 *                          be used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>result_table</code>.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for the result table. Must be used in
 *                          combination with the <code>result_table</code>
 *                          option.
 *                                  <li> 'create_indexes': Comma-separated list
 *                          of columns on which to create indexes on the result
 *                          table. Must be used in combination with the
 *                          <code>result_table</code> option.
 *                                  <li> 'view_id': view this result table is
 *                          part of.  The default value is ''.
 *                                  <li> 'materialize_on_gpu': If
 *                          <code>true</code> then the columns of the groupby
 *                          result table will be cached on the GPU. Must be
 *                          used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'pivot': pivot column
 *                                  <li> 'pivot_values': The value list
 *                          provided will become the column headers in the
 *                          output. Should be the values from the pivot_column.
 *                                  <li> 'grouping_sets': Customize the
 *                          grouping attribute sets to compute the aggregates.
 *                          These sets can include ROLLUP or CUBE operartors.
 *                          The attribute sets should be enclosed in
 *                          paranthesis and can include composite attributes.
 *                          All attributes specified in the grouping sets must
 *                          present in the groupby attributes.
 *                                  <li> 'rollup': This option is used to
 *                          specify the multilevel aggregates.
 *                                  <li> 'cube': This option is used to specify
 *                          the multidimensional aggregates.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_group_by = function(table_name, column_names, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_group_by(table_name, column_names, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_names: column_names,
        offset: offset,
        limit: (limit !== undefined && limit !== null) ? limit : 1000,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/aggregate/groupby", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Performs a histogram calculation given a table, a column, and an interval
 * function. The <code>interval</code> is used to produce bins of that size and
 * the result, computed over the records falling within each bin, is returned.
 * For each bin, the start value is inclusive, but the end value is
 * exclusive--except for the very last bin for which the end value is also
 * inclusive.  The value returned for each bin is the number of records in it,
 * except when a column name is provided as a <code>value_column</code>.  In
 * this latter case the sum of the values corresponding to the
 * <code>value_column</code> is used as the result instead.  The total number
 * of bins requested cannot exceed 10,000.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service a request that specifies a
 * <code>value_column</code> option.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_histogram_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_histogram_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_name: request.column_name,
        start: request.start,
        end: request.end,
        interval: request.interval,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/histogram", actual_request, callback);
};

/**
 * Performs a histogram calculation given a table, a column, and an interval
 * function. The <code>interval</code> is used to produce bins of that size and
 * the result, computed over the records falling within each bin, is returned.
 * For each bin, the start value is inclusive, but the end value is
 * exclusive--except for the very last bin for which the end value is also
 * inclusive.  The value returned for each bin is the number of records in it,
 * except when a column name is provided as a <code>value_column</code>.  In
 * this latter case the sum of the values corresponding to the
 * <code>value_column</code> is used as the result instead.  The total number
 * of bins requested cannot exceed 10,000.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service a request that specifies a
 * <code>value_column</code> option.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing table or
 *                             collection.
 * @param {String} column_name  Name of a column or an expression of one or
 *                              more column names over which the histogram will
 *                              be calculated.
 * @param {Number} start  Lower end value of the histogram interval, inclusive.
 * @param {Number} end  Upper end value of the histogram interval, inclusive.
 * @param {Number} interval  The size of each bin within the start and end
 *                           parameters.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'value_column': The name of the column
 *                          to use when calculating the bin values (values are
 *                          summed).  The column must be a numerical type (int,
 *                          double, long, float).
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_histogram = function(table_name, column_name, start, end, interval, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_histogram(table_name, column_name, start, end, interval, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_name: column_name,
        start: start,
        end: end,
        interval: interval,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/histogram", actual_request, callback);
};

/**
 * This endpoint runs the k-means algorithm - a heuristic algorithm that
 * attempts to do k-means clustering.  An ideal k-means clustering algorithm
 * selects k points such that the sum of the mean squared distances of each
 * member of the set to the nearest of the k points is minimized.  The k-means
 * algorithm however does not necessarily produce such an ideal cluster.   It
 * begins with a randomly selected set of k points and then refines the
 * location of the points iteratively and settles to a local minimum.  Various
 * parameters and options are provided to control the heuristic search.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service this request.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_k_means_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_k_means_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_names: request.column_names,
        k: request.k,
        tolerance: request.tolerance,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/kmeans", actual_request, callback);
};

/**
 * This endpoint runs the k-means algorithm - a heuristic algorithm that
 * attempts to do k-means clustering.  An ideal k-means clustering algorithm
 * selects k points such that the sum of the mean squared distances of each
 * member of the set to the nearest of the k points is minimized.  The k-means
 * algorithm however does not necessarily produce such an ideal cluster.   It
 * begins with a randomly selected set of k points and then refines the
 * location of the points iteratively and settles to a local minimum.  Various
 * parameters and options are provided to control the heuristic search.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service this request.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing table or
 *                             collection.
 * @param {String[]} column_names  List of column names on which the operation
 *                                 would be performed. If n columns are
 *                                 provided then each of the k result points
 *                                 will have n dimensions corresponding to the
 *                                 n columns.
 * @param {Number} k  The number of mean points to be determined by the
 *                    algorithm.
 * @param {Number} tolerance  Stop iterating when the distances between
 *                            successive points is less than the given
 *                            tolerance.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'whiten': When set to 1 each of the
 *                          columns is first normalized by its stdv - default
 *                          is not to whiten.
 *                                  <li> 'max_iters': Number of times to try to
 *                          hit the tolerance limit before giving up - default
 *                          is 10.
 *                                  <li> 'num_tries': Number of times to run
 *                          the k-means algorithm with a different randomly
 *                          selected starting points - helps avoid local
 *                          minimum. Default is 1.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_k_means = function(table_name, column_names, k, tolerance, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_k_means(table_name, column_names, k, tolerance, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_names: column_names,
        k: k,
        tolerance: tolerance,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/kmeans", actual_request, callback);
};

/**
 * Calculates and returns the minimum and maximum values of a particular column
 * in a table.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_min_max_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_min_max_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_name: request.column_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/minmax", actual_request, callback);
};

/**
 * Calculates and returns the minimum and maximum values of a particular column
 * in a table.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing table.
 * @param {String} column_name  Name of a column or an expression of one or
 *                              more column on which the min-max will be
 *                              calculated.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_min_max = function(table_name, column_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_min_max(table_name, column_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_name: column_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/minmax", actual_request, callback);
};

/**
 * Calculates and returns the minimum and maximum x- and y-coordinates of a
 * particular geospatial geometry column in a table.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_min_max_geometry_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_min_max_geometry_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_name: request.column_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/minmax/geometry", actual_request, callback);
};

/**
 * Calculates and returns the minimum and maximum x- and y-coordinates of a
 * particular geospatial geometry column in a table.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing table.
 * @param {String} column_name  Name of a geospatial geometry column on which
 *                              the min-max will be calculated.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_min_max_geometry = function(table_name, column_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_min_max_geometry(table_name, column_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_name: column_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/minmax/geometry", actual_request, callback);
};

/**
 * Calculates the requested statistics of the given column(s) in a given table.
 * <p>
 * The available statistics are <code>count</code> (number of total objects),
 * <code>mean</code>, <code>stdv</code> (standard deviation),
 * <code>variance</code>, <code>skew</code>, <code>kurtosis</code>,
 * <code>sum</code>, <code>min</code>, <code>max</code>,
 * <code>weighted_average</code>, <code>cardinality</code> (unique count),
 * <code>estimated_cardinality</code>, <code>percentile</code> and
 * <code>percentile_rank</code>.
 * <p>
 * Estimated cardinality is calculated by using the hyperloglog approximation
 * technique.
 * <p>
 * Percentiles and percentile ranks are approximate and are calculated using
 * the t-digest algorithm. They must include the desired
 * <code>percentile</code>/<code>percentile_rank</code>. To compute multiple
 * percentiles each value must be specified separately (i.e.
 * 'percentile(75.0),percentile(99.0),percentile_rank(1234.56),percentile_rank(-5)').
 * <p>
 * A second, comma-separated value can be added to the <code>percentile</code>
 * statistic to calculate percentile resolution, e.g., a 50th percentile with
 * 200 resolution would be 'percentile(50,200)'.
 * <p>
 * The weighted average statistic requires a <code>weight_column_name</code> to
 * be specified in <code>options</code>. The weighted average is then defined
 * as the sum of the products of <code>column_name</code> times the
 * <code>weight_column_name</code> values divided by the sum of the
 * <code>weight_column_name</code> values.
 * <p>
 * Additional columns can be used in the calculation of statistics via the
 * <code>additional_column_names</code> option.  Values in these columns will
 * be included in the overall aggregate calculation--individual aggregates will
 * not be calculated per additional column.  For instance, requesting the
 * <code>count</code> & <code>mean</code> of <code>column_name</code> x and
 * <code>additional_column_names</code> y & z, where x holds the numbers 1-10,
 * y holds 11-20, and z holds 21-30, would return the total number of x, y, & z
 * values (30), and the single average value across all x, y, & z values
 * (15.5).
 * <p>
 * The response includes a list of key/value pairs of each statistic requested
 * and its corresponding value.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_statistics_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_statistics_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_name: request.column_name,
        stats: request.stats,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/statistics", actual_request, callback);
};

/**
 * Calculates the requested statistics of the given column(s) in a given table.
 * <p>
 * The available statistics are <code>count</code> (number of total objects),
 * <code>mean</code>, <code>stdv</code> (standard deviation),
 * <code>variance</code>, <code>skew</code>, <code>kurtosis</code>,
 * <code>sum</code>, <code>min</code>, <code>max</code>,
 * <code>weighted_average</code>, <code>cardinality</code> (unique count),
 * <code>estimated_cardinality</code>, <code>percentile</code> and
 * <code>percentile_rank</code>.
 * <p>
 * Estimated cardinality is calculated by using the hyperloglog approximation
 * technique.
 * <p>
 * Percentiles and percentile ranks are approximate and are calculated using
 * the t-digest algorithm. They must include the desired
 * <code>percentile</code>/<code>percentile_rank</code>. To compute multiple
 * percentiles each value must be specified separately (i.e.
 * 'percentile(75.0),percentile(99.0),percentile_rank(1234.56),percentile_rank(-5)').
 * <p>
 * A second, comma-separated value can be added to the <code>percentile</code>
 * statistic to calculate percentile resolution, e.g., a 50th percentile with
 * 200 resolution would be 'percentile(50,200)'.
 * <p>
 * The weighted average statistic requires a <code>weight_column_name</code> to
 * be specified in <code>options</code>. The weighted average is then defined
 * as the sum of the products of <code>column_name</code> times the
 * <code>weight_column_name</code> values divided by the sum of the
 * <code>weight_column_name</code> values.
 * <p>
 * Additional columns can be used in the calculation of statistics via the
 * <code>additional_column_names</code> option.  Values in these columns will
 * be included in the overall aggregate calculation--individual aggregates will
 * not be calculated per additional column.  For instance, requesting the
 * <code>count</code> & <code>mean</code> of <code>column_name</code> x and
 * <code>additional_column_names</code> y & z, where x holds the numbers 1-10,
 * y holds 11-20, and z holds 21-30, would return the total number of x, y, & z
 * values (30), and the single average value across all x, y, & z values
 * (15.5).
 * <p>
 * The response includes a list of key/value pairs of each statistic requested
 * and its corresponding value.
 *
 * @param {String} table_name  Name of the table on which the statistics
 *                             operation will be performed.
 * @param {String} column_name  Name of the primary column for which the
 *                              statistics are to be calculated.
 * @param {String} stats  Comma separated list of the statistics to calculate,
 *                        e.g. "sum,mean".
 *                        Supported values:
 *                        <ul>
 *                                <li> 'count': Number of objects (independent
 *                        of the given column(s)).
 *                                <li> 'mean': Arithmetic mean (average),
 *                        equivalent to sum/count.
 *                                <li> 'stdv': Sample standard deviation
 *                        (denominator is count-1).
 *                                <li> 'variance': Unbiased sample variance
 *                        (denominator is count-1).
 *                                <li> 'skew': Skewness (third standardized
 *                        moment).
 *                                <li> 'kurtosis': Kurtosis (fourth
 *                        standardized moment).
 *                                <li> 'sum': Sum of all values in the
 *                        column(s).
 *                                <li> 'min': Minimum value of the column(s).
 *                                <li> 'max': Maximum value of the column(s).
 *                                <li> 'weighted_average': Weighted arithmetic
 *                        mean (using the option
 *                        <code>weight_column_name</code> as the weighting
 *                        column).
 *                                <li> 'cardinality': Number of unique values
 *                        in the column(s).
 *                                <li> 'estimated_cardinality': Estimate (via
 *                        hyperloglog technique) of the number of unique values
 *                        in the column(s).
 *                                <li> 'percentile': Estimate (via t-digest) of
 *                        the given percentile of the column(s)
 *                        (percentile(50.0) will be an approximation of the
 *                        median). Add a second, comma-separated value to
 *                        calculate percentile resolution, e.g.,
 *                        'percentile(75,150)'
 *                                <li> 'percentile_rank': Estimate (via
 *                        t-digest) of the percentile rank of the given value
 *                        in the column(s) (if the given value is the median of
 *                        the column(s), percentile_rank(<median>) will return
 *                        approximately 50.0).
 *                        </ul>
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'additional_column_names': A list of
 *                          comma separated column names over which statistics
 *                          can be accumulated along with the primary column.
 *                          All columns listed and <code>column_name</code>
 *                          must be of the same type.  Must not include the
 *                          column specified in <code>column_name</code> and no
 *                          column can be listed twice.
 *                                  <li> 'weight_column_name': Name of column
 *                          used as weighting attribute for the weighted
 *                          average statistic.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_statistics = function(table_name, column_name, stats, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_statistics(table_name, column_name, stats, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_name: column_name,
        stats: stats,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/statistics", actual_request, callback);
};

/**
 * Divides the given set into bins and calculates statistics of the values of a
 * value-column in each bin.  The bins are based on the values of a given
 * binning-column.  The statistics that may be requested are mean, stdv
 * (standard deviation), variance, skew, kurtosis, sum, min, max, first, last
 * and weighted average. In addition to the requested statistics the count of
 * total samples in each bin is returned. This counts vector is just the
 * histogram of the column used to divide the set members into bins. The
 * weighted average statistic requires a weight_column to be specified in
 * <code>options</code>. The weighted average is then defined as the sum of the
 * products of the value column times the weight column divided by the sum of
 * the weight column.
 * <p>
 * There are two methods for binning the set members. In the first, which can
 * be used for numeric valued binning-columns, a min, max and interval are
 * specified. The number of bins, nbins, is the integer upper bound of
 * (max-min)/interval. Values that fall in the range
 * [min+n*interval,min+(n+1)*interval) are placed in the nth bin where n ranges
 * from 0..nbin-2. The final bin is [min+(nbin-1)*interval,max]. In the second
 * method, <code>options</code> bin_values specifies a list of binning column
 * values. Binning-columns whose value matches the nth member of the bin_values
 * list are placed in the nth bin. When a list is provided the binning-column
 * must be of type string or int.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service this request.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_statistics_by_range_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_statistics_by_range_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        select_expression: (request.select_expression !== undefined && request.select_expression !== null) ? request.select_expression : "",
        column_name: request.column_name,
        value_column_name: request.value_column_name,
        stats: request.stats,
        start: request.start,
        end: request.end,
        interval: request.interval,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/aggregate/statistics/byrange", actual_request, callback);
};

/**
 * Divides the given set into bins and calculates statistics of the values of a
 * value-column in each bin.  The bins are based on the values of a given
 * binning-column.  The statistics that may be requested are mean, stdv
 * (standard deviation), variance, skew, kurtosis, sum, min, max, first, last
 * and weighted average. In addition to the requested statistics the count of
 * total samples in each bin is returned. This counts vector is just the
 * histogram of the column used to divide the set members into bins. The
 * weighted average statistic requires a weight_column to be specified in
 * <code>options</code>. The weighted average is then defined as the sum of the
 * products of the value column times the weight column divided by the sum of
 * the weight column.
 * <p>
 * There are two methods for binning the set members. In the first, which can
 * be used for numeric valued binning-columns, a min, max and interval are
 * specified. The number of bins, nbins, is the integer upper bound of
 * (max-min)/interval. Values that fall in the range
 * [min+n*interval,min+(n+1)*interval) are placed in the nth bin where n ranges
 * from 0..nbin-2. The final bin is [min+(nbin-1)*interval,max]. In the second
 * method, <code>options</code> bin_values specifies a list of binning column
 * values. Binning-columns whose value matches the nth member of the bin_values
 * list are placed in the nth bin. When a list is provided the binning-column
 * must be of type string or int.
 * <p>
 * NOTE:  The Kinetica instance being accessed must be running a CUDA
 * (GPU-based) build to service this request.
 *
 * @param {String} table_name  Name of the table on which the ranged-statistics
 *                             operation will be performed.
 * @param {String} select_expression  For a non-empty expression statistics are
 *                                    calculated for those records for which
 *                                    the expression is true.
 * @param {String} column_name  Name of the binning-column used to divide the
 *                              set samples into bins.
 * @param {String} value_column_name  Name of the value-column for which
 *                                    statistics are to be computed.
 * @param {String} stats  A string of comma separated list of the statistics to
 *                        calculate, e.g. 'sum,mean'. Available statistics:
 *                        mean, stdv (standard deviation), variance, skew,
 *                        kurtosis, sum.
 * @param {Number} start  The lower bound of the binning-column.
 * @param {Number} end  The upper bound of the binning-column.
 * @param {Number} interval  The interval of a bin. Set members fall into bin i
 *                           if the binning-column falls in the range
 *                           [start+interval*i, start+interval*(i+1)).
 * @param {Object} options  Map of optional parameters:
 *                          <ul>
 *                                  <li> 'additional_column_names': A list of
 *                          comma separated value-column names over which
 *                          statistics can be accumulated along with the
 *                          primary value_column.
 *                                  <li> 'bin_values': A list of comma
 *                          separated binning-column values. Values that match
 *                          the nth bin_values value are placed in the nth bin.
 *                                  <li> 'weight_column_name': Name of the
 *                          column used as weighting column for the
 *                          weighted_average statistic.
 *                                  <li> 'order_column_name': Name of the
 *                          column used for candlestick charting techniques.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_statistics_by_range = function(table_name, select_expression, column_name, value_column_name, stats, start, end, interval, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_statistics_by_range(table_name, select_expression, column_name, value_column_name, stats, start, end, interval, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        select_expression: (select_expression !== undefined && select_expression !== null) ? select_expression : "",
        column_name: column_name,
        value_column_name: value_column_name,
        stats: stats,
        start: start,
        end: end,
        interval: interval,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/aggregate/statistics/byrange", actual_request, callback);
};

/**
 * Returns all the unique values from a particular column (specified by
 * <code>column_name</code>) of a particular table or collection (specified by
 * <code>table_name</code>). If <code>column_name</code> is a numeric column
 * the values will be in <code>binary_encoded_response</code>. Otherwise if
 * <code>column_name</code> is a string column the values will be in
 * <code>json_encoded_response</code>.  The results can be paged via the
 * <code>offset</code> and <code>limit</code> parameters.
 * <p>
 * Columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a> are unable to be used with this function.
 * <p>
 * To get the first 10 unique values sorted in descending order
 * <code>options</code> would be::
 * <p>
 * {"limit":"10","sort_order":"descending"}.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 * <p>
 * If a <code>result_table</code> name is specified in the
 * <code>options</code>, the results are stored in a new table with that
 * name--no results are returned in the response.  Both the table name and
 * resulting column name must adhere to <a
 * href="../../concepts/tables.html#table" target="_top">standard naming
 * conventions</a>; any column expression will need to be aliased.  If the
 * source table's <a href="../../concepts/tables.html#shard-keys"
 * target="_top">shard key</a> is used as the <code>column_name</code>, the
 * result table will be sharded, in all other cases it will be replicated.
 * Sorting will properly function only if the result table is replicated or if
 * there is only one processing node and should not be relied upon in other
 * cases.  Not available if <code>table_name</code> is a collection or when the
 * value of <code>column_name</code> is an unrestricted-length string.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_unique_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_unique_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_name: request.column_name,
        offset: request.offset,
        limit: (request.limit !== undefined && request.limit !== null) ? request.limit : 10000,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/aggregate/unique", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Returns all the unique values from a particular column (specified by
 * <code>column_name</code>) of a particular table or collection (specified by
 * <code>table_name</code>). If <code>column_name</code> is a numeric column
 * the values will be in <code>binary_encoded_response</code>. Otherwise if
 * <code>column_name</code> is a string column the values will be in
 * <code>json_encoded_response</code>.  The results can be paged via the
 * <code>offset</code> and <code>limit</code> parameters.
 * <p>
 * Columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a> are unable to be used with this function.
 * <p>
 * To get the first 10 unique values sorted in descending order
 * <code>options</code> would be::
 * <p>
 * {"limit":"10","sort_order":"descending"}.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 * <p>
 * If a <code>result_table</code> name is specified in the
 * <code>options</code>, the results are stored in a new table with that
 * name--no results are returned in the response.  Both the table name and
 * resulting column name must adhere to <a
 * href="../../concepts/tables.html#table" target="_top">standard naming
 * conventions</a>; any column expression will need to be aliased.  If the
 * source table's <a href="../../concepts/tables.html#shard-keys"
 * target="_top">shard key</a> is used as the <code>column_name</code>, the
 * result table will be sharded, in all other cases it will be replicated.
 * Sorting will properly function only if the result table is replicated or if
 * there is only one processing node and should not be relied upon in other
 * cases.  Not available if <code>table_name</code> is a collection or when the
 * value of <code>column_name</code> is an unrestricted-length string.
 *
 * @param {String} table_name  Name of an existing table/collection on which
 *                             the operation will be performed.
 * @param {String} column_name  Name of the column or an expression containing
 *                              one or more column names on which the unique
 *                              function would be applied.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned. Or END_OF_SET (-9999) to
 *                        indicate that the max number of results should be
 *                        returned.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the table specified
 *                          in <code>result_table</code>. If the collection
 *                          provided is non-existent, the collection will be
 *                          automatically created. If empty, then the table
 *                          will be a top-level table.  Additionally this
 *                          option is invalid if <code>table_name</code> is a
 *                          collection.
 *                                  <li> 'expression': Optional filter
 *                          expression to apply to the table.
 *                                  <li> 'sort_order': String indicating how
 *                          the returned values should be sorted.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'ascending'
 *                                  <li> 'descending'
 *                          </ul>
 *                          The default value is 'ascending'.
 *                                  <li> 'result_table': The name of the table
 *                          used to store the results. If present, no results
 *                          are returned in the response. Has the same naming
 *                          restrictions as <a
 *                          href="../../concepts/tables.html"
 *                          target="_top">tables</a>.  Not available if
 *                          <code>table_name</code> is a collection or when
 *                          <code>column_name</code> is an unrestricted-length
 *                          string.
 *                                  <li> 'result_table_persist': If
 *                          <code>true</code>, then the result table specified
 *                          in <code>result_table</code> will be persisted and
 *                          will not expire unless a <code>ttl</code> is
 *                          specified.   If <code>false</code>, then the result
 *                          table will be an in-memory table and will expire
 *                          unless a <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'result_table_force_replicated': Force
 *                          the result table to be replicated (ignores any
 *                          sharding). Must be used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'result_table_generate_pk': If 'true'
 *                          then set a primary key for the result table. Must
 *                          be used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>result_table</code>.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for the result table. Must be used in
 *                          combination with the <code>result_table</code>
 *                          option.
 *                                  <li> 'view_id': view this result table is
 *                          part of.  The default value is ''.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_unique = function(table_name, column_name, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_unique(table_name, column_name, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_name: column_name,
        offset: offset,
        limit: (limit !== undefined && limit !== null) ? limit : 10000,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/aggregate/unique", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Rotate the column values into rows values.
 * <p>
 * For unpivot details and examples, see <a href="../../concepts/unpivot.html"
 * target="_top">Unpivot</a>.  For limitations, see <a
 * href="../../concepts/unpivot.html#limitations" target="_top">Unpivot
 * Limitations</a>.
 * <p>
 * Unpivot is used to normalize tables that are built for cross tabular
 * reporting purposes. The unpivot operator rotates the column values for all
 * the pivoted columns. A variable column, value column and all columns from
 * the source table except the unpivot columns are projected into the result
 * table. The variable column and value columns in the result table indicate
 * the pivoted column name and values respectively.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_unpivot_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_unpivot_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_names: request.column_names,
        variable_column_name: (request.variable_column_name !== undefined && request.variable_column_name !== null) ? request.variable_column_name : "",
        value_column_name: (request.value_column_name !== undefined && request.value_column_name !== null) ? request.value_column_name : "",
        pivoted_columns: request.pivoted_columns,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/aggregate/unpivot", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Rotate the column values into rows values.
 * <p>
 * For unpivot details and examples, see <a href="../../concepts/unpivot.html"
 * target="_top">Unpivot</a>.  For limitations, see <a
 * href="../../concepts/unpivot.html#limitations" target="_top">Unpivot
 * Limitations</a>.
 * <p>
 * Unpivot is used to normalize tables that are built for cross tabular
 * reporting purposes. The unpivot operator rotates the column values for all
 * the pivoted columns. A variable column, value column and all columns from
 * the source table except the unpivot columns are projected into the result
 * table. The variable column and value columns in the result table indicate
 * the pivoted column name and values respectively.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 *
 * @param {String} table_name  Name of the table on which the operation will be
 *                             performed. Must be an existing table/view.
 * @param {String[]} column_names  List of column names or expressions. A
 *                                 wildcard '*' can be used to include all the
 *                                 non-pivoted columns from the source table.
 * @param {String} variable_column_name  Specifies the variable/parameter
 *                                       column name.
 * @param {String} value_column_name  Specifies the value column name.
 * @param {String[]} pivoted_columns  List of one or more values typically the
 *                                    column names of the input table. All the
 *                                    columns in the source table must have the
 *                                    same data type.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the table specified
 *                          in <code>result_table</code>. If the collection
 *                          provided is non-existent, the collection will be
 *                          automatically created. If empty, then the table
 *                          will be a top-level table.
 *                                  <li> 'result_table': The name of the table
 *                          used to store the results. Has the same naming
 *                          restrictions as <a
 *                          href="../../concepts/tables.html"
 *                          target="_top">tables</a>. If present, no results
 *                          are returned in the response.
 *                                  <li> 'result_table_persist': If
 *                          <code>true</code>, then the result table specified
 *                          in <code>result_table</code> will be persisted and
 *                          will not expire unless a <code>ttl</code> is
 *                          specified.   If <code>false</code>, then the result
 *                          table will be an in-memory table and will expire
 *                          unless a <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'expression': Filter expression to
 *                          apply to the table prior to unpivot processing.
 *                                  <li> 'order_by': Comma-separated list of
 *                          the columns to be sorted by; e.g. 'timestamp asc, x
 *                          desc'.  The columns specified must be present in
 *                          input table.  If any alias is given for any column
 *                          name, the alias must be used, rather than the
 *                          original column name.  The default value is ''.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for the result table. Must be used in
 *                          combination with the <code>result_table</code>
 *                          option.
 *                                  <li> 'limit': The number of records to
 *                          keep.  The default value is ''.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>result_table</code>.
 *                                  <li> 'view_id': view this result table is
 *                          part of.  The default value is ''.
 *                                  <li> 'materialize_on_gpu': If
 *                          <code>true</code> then the output columns will be
 *                          cached on the GPU.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'create_indexes': Comma-separated list
 *                          of columns on which to create indexes on the table
 *                          specified in <code>result_table</code>. The columns
 *                          specified must be present in output column names.
 *                          If any alias is given for any column name, the
 *                          alias must be used, rather than the original column
 *                          name.
 *                                  <li> 'result_table_force_replicated': Force
 *                          the result table to be replicated (ignores any
 *                          sharding). Must be used in combination with the
 *                          <code>result_table</code> option.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.aggregate_unpivot = function(table_name, column_names, variable_column_name, value_column_name, pivoted_columns, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.aggregate_unpivot(table_name, column_names, variable_column_name, value_column_name, pivoted_columns, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_names: column_names,
        variable_column_name: (variable_column_name !== undefined && variable_column_name !== null) ? variable_column_name : "",
        value_column_name: (value_column_name !== undefined && value_column_name !== null) ? value_column_name : "",
        pivoted_columns: pivoted_columns,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/aggregate/unpivot", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * The {@linkcode GPUdb#alter_system_properties} endpoint is primarily used
 * to simplify the testing of the system and is not expected to be used during
 * normal execution.  Commands are given through the
 * <code>property_updates_map</code> whose keys are commands and values are
 * strings representing integer values (for example '8000') or boolean values
 * ('true' or 'false').
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_system_properties_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_system_properties_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        property_updates_map: request.property_updates_map,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/alter/system/properties", actual_request, callback);
};

/**
 * The {@linkcode GPUdb#alter_system_properties} endpoint is primarily used
 * to simplify the testing of the system and is not expected to be used during
 * normal execution.  Commands are given through the
 * <code>property_updates_map</code> whose keys are commands and values are
 * strings representing integer values (for example '8000') or boolean values
 * ('true' or 'false').
 *
 * @param {Object} property_updates_map  Map containing the properties of the
 *                                       system to be updated. Error if empty.
 *                                       <ul>
 *                                               <li> 'sm_omp_threads': Set the
 *                                       number of OpenMP threads that will be
 *                                       used to service filter & aggregation
 *                                       requests against collections to the
 *                                       specified integer value.
 *                                               <li> 'kernel_omp_threads': Set
 *                                       the number of kernel OpenMP threads to
 *                                       the specified integer value.
 *                                               <li>
 *                                       'concurrent_kernel_execution': Enables
 *                                       concurrent kernel execution if the
 *                                       value is <code>true</code> and
 *                                       disables it if the value is
 *                                       <code>false</code>.
 *                                       Supported values:
 *                                       <ul>
 *                                               <li> 'true'
 *                                               <li> 'false'
 *                                       </ul>
 *                                               <li> 'chunk_size': Sets the
 *                                       chunk size of all new sets to the
 *                                       specified integer value.
 *                                               <li> 'execution_mode': Sets
 *                                       the execution_mode for kernel
 *                                       executions to the specified string
 *                                       value. Possible values are host,
 *                                       device, default (engine decides) or an
 *                                       integer value that indicates max chunk
 *                                       size to exec on host
 *                                               <li> 'flush_to_disk': Flushes
 *                                       any changes to any tables to the
 *                                       persistent store.  These changes
 *                                       include updates to the vector store,
 *                                       object store, and text search store,
 *                                       Value string is ignored
 *                                               <li> 'clear_cache': Clears
 *                                       cached results.  Useful to allow
 *                                       repeated timing of endpoints. Value
 *                                       string is ignored
 *                                               <li> 'communicator_test':
 *                                       Invoke the communicator test and
 *                                       report timing results. Value string is
 *                                       is a comma separated list of
 *                                       <key>=<value> expressions.
 *                                       Expressions are:
 *                                       num_transactions=<num> where num is
 *                                       the number of request reply
 *                                       transactions to invoke per test;
 *                                       message_size=<bytes> where bytes is
 *                                       the size of the messages to send in
 *                                       bytes; check_values=<enabled> where if
 *                                       enabled is true the value of the
 *                                       messages received are verified.
 *                                               <li>
 *                                       'set_message_timers_enabled': Enables
 *                                       the communicator test to collect
 *                                       additional timing statistics when the
 *                                       value string is <code>true</code>.
 *                                       Disables the collection when the value
 *                                       string is <code>false</code>
 *                                       Supported values:
 *                                       <ul>
 *                                               <li> 'true'
 *                                               <li> 'false'
 *                                       </ul>
 *                                               <li> 'bulk_add_test': Invoke
 *                                       the bulk add test and report timing
 *                                       results. Value string is ignored.
 *                                               <li> 'network_speed': Invoke
 *                                       the network speed test and report
 *                                       timing results. Value string is a
 *                                       semicolon-separated list of
 *                                       <key>=<value> expressions.  Valid
 *                                       expressions are: seconds=<time> where
 *                                       time is the time in seconds to run the
 *                                       test; data_size=<size> where size is
 *                                       the size in bytes of the block to be
 *                                       transferred; threads=<number of
 *                                       threads>; to_ranks=<space-separated
 *                                       list of ranks> where the list of ranks
 *                                       is the ranks that rank 0 will send
 *                                       data to and get data from. If to_ranks
 *                                       is unspecified then all worker ranks
 *                                       are used.
 *                                               <li> 'request_timeout': Number
 *                                       of minutes after which filtering
 *                                       (e.g., {@linkcode GPUdb#filter}) and
 *                                       aggregating (e.g.,
 *                                       {@linkcode GPUdb#aggregate_group_by})
 *                                       queries will timeout.  The default
 *                                       value is '20'.
 *                                               <li> 'max_get_records_size':
 *                                       The maximum number of records the
 *                                       database will serve for a given data
 *                                       retrieval call.  The default value is
 *                                       '20000'.
 *                                               <li>
 *                                       'memory_allocation_limit_mb': Set the
 *                                       memory allocation limit for all rank
 *                                       processes in megabytes, 0 means no
 *                                       limit. Overrides any individual rank
 *                                       memory allocation limits.  The default
 *                                       value is '0'.
 *                                               <li> 'enable_audit': Enable or
 *                                       disable auditing.
 *                                               <li> 'audit_headers': Enable
 *                                       or disable auditing of request
 *                                       headers.
 *                                               <li> 'audit_body': Enable or
 *                                       disable auditing of request bodies.
 *                                               <li> 'audit_data': Enable or
 *                                       disable auditing of request data.
 *                                               <li> 'enable_job_manager':
 *                                       Enable JobManager to enforce
 *                                       processing of requests in the order
 *                                       received.
 *                                               <li> 'chunk_cache_enabled':
 *                                       Enable chunk level query caching.
 *                                       Flushes the chunk cache when value is
 *                                       false
 *                                               <li> 'chunk_cache_size': Size
 *                                       of the chunk cache in bytes.  The
 *                                       default value is '10000000'.
 *                                       </ul>
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_system_properties = function(property_updates_map, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_system_properties(property_updates_map, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        property_updates_map: property_updates_map,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/alter/system/properties", actual_request, callback);
};

/**
 * Apply various modifications to a table, view, or collection.  The available
 * modifications include the following:
 * <p>
 * Create or delete an <a href="../../concepts/indexes.html#column-index"
 * target="_top">index</a> on a
 * particular column. This can speed up certain operations when using
 * expressions
 * containing equality or relational operators on indexed columns. This only
 * applies to tables.
 * <p>
 * Set the <a href="../../concepts/ttl.html" target="_top">time-to-live
 * (TTL)</a>. This can be applied
 * to tables, views, or collections.  When applied to collections, every
 * contained
 * table & view that is not protected will have its TTL set to the given value.
 * <p>
 * Set the global access mode (i.e. locking) for a table. This setting trumps
 * any
 * role-based access controls that may be in place; e.g., a user with write
 * access
 * to a table marked read-only will not be able to insert records into it. The
 * mode
 * can be set to read-only, write-only, read/write, and no access.
 * <p>
 * Change the <a href="../../concepts/protection.html"
 * target="_top">protection</a> mode to prevent or
 * allow automatic expiration. This can be applied to tables, views, and
 * collections.
 * <p>
 * Allow homogeneous tables within a collection.
 * <p>
 * Manage a table's columns--a column can be added, removed, or have its
 * <a href="../../concepts/types.html" target="_top">type and properties</a>
 * modified.
 * <p>
 * Set or unset <a href="../../concepts/compression.html"
 * target="_top">compression</a> for a column.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        action: request.action,
        value: request.value,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/alter/table", actual_request, callback);
};

/**
 * Apply various modifications to a table, view, or collection.  The available
 * modifications include the following:
 * <p>
 * Create or delete an <a href="../../concepts/indexes.html#column-index"
 * target="_top">index</a> on a
 * particular column. This can speed up certain operations when using
 * expressions
 * containing equality or relational operators on indexed columns. This only
 * applies to tables.
 * <p>
 * Set the <a href="../../concepts/ttl.html" target="_top">time-to-live
 * (TTL)</a>. This can be applied
 * to tables, views, or collections.  When applied to collections, every
 * contained
 * table & view that is not protected will have its TTL set to the given value.
 * <p>
 * Set the global access mode (i.e. locking) for a table. This setting trumps
 * any
 * role-based access controls that may be in place; e.g., a user with write
 * access
 * to a table marked read-only will not be able to insert records into it. The
 * mode
 * can be set to read-only, write-only, read/write, and no access.
 * <p>
 * Change the <a href="../../concepts/protection.html"
 * target="_top">protection</a> mode to prevent or
 * allow automatic expiration. This can be applied to tables, views, and
 * collections.
 * <p>
 * Allow homogeneous tables within a collection.
 * <p>
 * Manage a table's columns--a column can be added, removed, or have its
 * <a href="../../concepts/types.html" target="_top">type and properties</a>
 * modified.
 * <p>
 * Set or unset <a href="../../concepts/compression.html"
 * target="_top">compression</a> for a column.
 *
 * @param {String} table_name  Table on which the operation will be performed.
 *                             Must be an existing table, view, or collection.
 * @param {String} action  Modification operation to be applied
 *                         Supported values:
 *                         <ul>
 *                                 <li> 'allow_homogeneous_tables': Sets
 *                         whether homogeneous tables are allowed in the given
 *                         collection. This action is only valid if
 *                         <code>table_name</code> is a collection. The
 *                         <code>value</code> must be either 'true' or 'false'.
 *                                 <li> 'create_index': Creates an <a
 *                         href="../../concepts/indexes.html#column-index"
 *                         target="_top">index</a> on the column name specified
 *                         in <code>value</code>. If this column is already
 *                         indexed, an error will be returned.
 *                                 <li> 'delete_index': Deletes an existing <a
 *                         href="../../concepts/indexes.html#column-index"
 *                         target="_top">index</a> on the column name specified
 *                         in <code>value</code>. If this column does not have
 *                         indexing turned on, an error will be returned.
 *                                 <li> 'move_to_collection': Moves a table
 *                         into a collection <code>value</code>.
 *                                 <li> 'protected': Sets whether the given
 *                         <code>table_name</code> should be <a
 *                         href="../../concepts/protection.html"
 *                         target="_top">protected</a> or not. The
 *                         <code>value</code> must be either 'true' or 'false'.
 *                                 <li> 'rename_table': Renames a table, view
 *                         or collection to <code>value</code>. Has the same
 *                         naming restrictions as <a
 *                         href="../../concepts/tables.html"
 *                         target="_top">tables</a>.
 *                                 <li> 'ttl': Sets the <a
 *                         href="../../concepts/ttl.html"
 *                         target="_top">time-to-live</a> in minutes of the
 *                         table, view, or collection specified in
 *                         <code>table_name</code>.
 *                                 <li> 'memory_ttl': Sets the time-to-live in
 *                         minutes for the individual chunks of the columns of
 *                         the table, view, or collection specified in
 *                         <code>table_name</code> to free their memory if
 *                         unused longer than the given time. Specify an empty
 *                         string to restore the global memory_ttl setting and
 *                         a value of '-1' for an infinite timeout.
 *                                 <li> 'add_column': Adds the column specified
 *                         in <code>value</code> to the table specified in
 *                         <code>table_name</code>.  Use
 *                         <code>column_type</code> and
 *                         <code>column_properties</code> in
 *                         <code>options</code> to set the column's type and
 *                         properties, respectively.
 *                                 <li> 'change_column': Changes type and
 *                         properties of the column specified in
 *                         <code>value</code>.  Use <code>column_type</code>
 *                         and <code>column_properties</code> in
 *                         <code>options</code> to set the column's type and
 *                         properties, respectively. Note that primary key
 *                         and/or shard key columns cannot be changed. All
 *                         unchanging column properties must be listed for the
 *                         change to take place, e.g., to add dictionary
 *                         encoding to an existing 'char4' column, both 'char4'
 *                         and 'dict' must be specified in the
 *                         <code>options</code> map.
 *                                 <li> 'set_column_compression': Modifies the
 *                         <a href="../../concepts/compression.html"
 *                         target="_top">compression</a> setting on the column
 *                         specified in <code>value</code>.
 *                                 <li> 'delete_column': Deletes the column
 *                         specified in <code>value</code> from the table
 *                         specified in <code>table_name</code>.
 *                                 <li> 'create_foreign_key': Creates a <a
 *                         href="../../concepts/tables.html#foreign-key"
 *                         target="_top">foreign key</a> using the format
 *                         '(source_column_name [, ...]) references
 *                         target_table_name(primary_key_column_name [, ...])
 *                         [as foreign_key_name]'.
 *                                 <li> 'delete_foreign_key': Deletes a <a
 *                         href="../../concepts/tables.html#foreign-key"
 *                         target="_top">foreign key</a>.  The
 *                         <code>value</code> should be the foreign_key_name
 *                         specified when creating the key or the complete
 *                         string used to define it.
 *                                 <li> 'set_global_access_mode': Sets the
 *                         global access mode (i.e. locking) for the table
 *                         specified in <code>table_name</code>. Specify the
 *                         access mode in <code>value</code>. Valid modes are
 *                         'no_access', 'read_only', 'write_only' and
 *                         'read_write'.
 *                                 <li> 'refresh': Replays all the table
 *                         creation commands required to create this <a
 *                         href="../../concepts/materialized_views.html"
 *                         target="_top">materialized view</a>.
 *                                 <li> 'set_refresh_method': Sets the method
 *                         by which this <a
 *                         href="../../concepts/materialized_views.html"
 *                         target="_top">materialized view</a> is refreshed -
 *                         one of 'manual', 'periodic', 'on_change'.
 *                                 <li> 'set_refresh_start_time': Sets the time
 *                         to start periodic refreshes of this <a
 *                         href="../../concepts/materialized_views.html"
 *                         target="_top">materialized view</a> to datetime
 *                         string with format 'YYYY-MM-DD HH:MM:SS'.
 *                         Subsequent refreshes occur at the specified time + N
 *                         * the refresh period.
 *                                 <li> 'set_refresh_period': Sets the time
 *                         interval in seconds at which to refresh this <a
 *                         href="../../concepts/materialized_views.html"
 *                         target="_top">materialized view</a>.  Also, sets the
 *                         refresh method to periodic if not alreay set.
 *                                 <li> 'remove_text_search_attributes': remove
 *                         text_search attribute from all columns, if exists.
 *                         </ul>
 * @param {String} value  The value of the modification. May be a column name,
 *                        'true' or 'false', a TTL, or the global access mode
 *                        depending on <code>action</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'column_default_value': When adding a
 *                          column, set a default value for existing records.
 *                          For nullable columns, the default value will be
 *                          null, regardless of data type.
 *                                  <li> 'column_properties': When adding or
 *                          changing a column, set the column properties
 *                          (strings, separated by a comma: data, store_only,
 *                          text_search, char8, int8 etc).
 *                                  <li> 'column_type': When adding or changing
 *                          a column, set the column type (strings, separated
 *                          by a comma: int, double, string, null etc).
 *                                  <li> 'compression_type': When setting
 *                          column compression
 *                          (<code>set_column_compression</code> for
 *                          <code>action</code>), compression type to use:
 *                          <code>none</code> (to use no compression) or a
 *                          valid compression type.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'none'
 *                                  <li> 'snappy'
 *                                  <li> 'lz4'
 *                                  <li> 'lz4hc'
 *                          </ul>
 *                          The default value is 'snappy'.
 *                                  <li> 'copy_values_from_column': please see
 *                          add_column_expression instead.
 *                                  <li> 'rename_column': When changing a
 *                          column, specify new column name.
 *                                  <li> 'validate_change_column': When
 *                          changing a column, validate the change before
 *                          applying it. If <code>true</code>, then validate
 *                          all values. A value too large (or too long) for the
 *                          new type will prevent any change. If
 *                          <code>false</code>, then when a value is too large
 *                          or long, it will be truncated.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true': true
 *                                  <li> 'false': false
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'update_last_access_time': Indicates
 *                          whether need to update the last_access_time.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'add_column_expression': expression
 *                          for new column's values (optional with add_column).
 *                          Any valid expressions including existing columns.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_table = function(table_name, action, value, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_table(table_name, action, value, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        action: action,
        value: value,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/alter/table", actual_request, callback);
};

/**
 * Updates (adds or changes) metadata for tables. The metadata key and values
 * must both be strings. This is an easy way to annotate whole tables rather
 * than single records within tables.  Some examples of metadata are owner of
 * the table, table creation timestamp etc.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_table_metadata_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_table_metadata_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        metadata_map: request.metadata_map,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/alter/table/metadata", actual_request, callback);
};

/**
 * Updates (adds or changes) metadata for tables. The metadata key and values
 * must both be strings. This is an easy way to annotate whole tables rather
 * than single records within tables.  Some examples of metadata are owner of
 * the table, table creation timestamp etc.
 *
 * @param {String[]} table_names  Names of the tables whose metadata will be
 *                                updated. All specified tables must exist, or
 *                                an error will be returned.
 * @param {Object} metadata_map  A map which contains the metadata of the
 *                               tables that are to be updated. Note that only
 *                               one map is provided for all the tables; so the
 *                               change will be applied to every table. If the
 *                               provided map is empty, then all existing
 *                               metadata for the table(s) will be cleared.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_table_metadata = function(table_names, metadata_map, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_table_metadata(table_names, metadata_map, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        metadata_map: metadata_map,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/alter/table/metadata", actual_request, callback);
};

/**
 * Alters a user.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_user_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_user_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        action: request.action,
        value: request.value,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/alter/user", actual_request, callback);
};

/**
 * Alters a user.
 *
 * @param {String} name  Name of the user to be altered. Must be an existing
 *                       user.
 * @param {String} action  Modification operation to be applied to the user.
 *                         Supported values:
 *                         <ul>
 *                                 <li> 'set_password': Sets the password of
 *                         the user. The user must be an internal user.
 *                         </ul>
 * @param {String} value  The value of the modification, depending on
 *                        <code>action</code>.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.alter_user = function(name, action, value, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.alter_user(name, action, value, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        action: action,
        value: value,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/alter/user", actual_request, callback);
};

/**
 * Append (or insert) all records from a source table (specified by
 * <code>source_table_name</code>) to a particular target table (specified by
 * <code>table_name</code>). The field map (specified by
 * <code>field_map</code>) holds the user specified map of target table column
 * names with their mapped source column names.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.append_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.append_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        source_table_name: request.source_table_name,
        field_map: request.field_map,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/append/records", actual_request, callback);
};

/**
 * Append (or insert) all records from a source table (specified by
 * <code>source_table_name</code>) to a particular target table (specified by
 * <code>table_name</code>). The field map (specified by
 * <code>field_map</code>) holds the user specified map of target table column
 * names with their mapped source column names.
 *
 * @param {String} table_name  The table name for the records to be appended.
 *                             Must be an existing table.
 * @param {String} source_table_name  The source table name to get records
 *                                    from. Must be an existing table name.
 * @param {Object} field_map  Contains the mapping of column names from the
 *                            target table (specified by
 *                            <code>table_name</code>) as the keys, and
 *                            corresponding column names or expressions (e.g.,
 *                            'col_name+1') from the source table (specified by
 *                            <code>source_table_name</code>). Must be existing
 *                            column names in source table and target table,
 *                            and their types must be matched. For details on
 *                            using expressions, see <a
 *                            href="../../concepts/expressions.html"
 *                            target="_top">Expressions</a>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'offset': A positive integer
 *                          indicating the number of initial results to skip
 *                          from source table (specified by
 *                          <code>source_table_name</code>). Default is 0. The
 *                          minimum allowed value is 0. The maximum allowed
 *                          value is MAX_INT.  The default value is '0'.
 *                                  <li> 'limit': A positive integer indicating
 *                          the maximum number of results to be returned from
 *                          source table (specified by
 *                          <code>source_table_name</code>). Or END_OF_SET
 *                          (-9999) to indicate that the max number of results
 *                          should be returned.  The default value is '-9999'.
 *                                  <li> 'expression': Optional filter
 *                          expression to apply to the source table (specified
 *                          by <code>source_table_name</code>). Empty by
 *                          default.  The default value is ''.
 *                                  <li> 'order_by': Comma-separated list of
 *                          the columns and expressions to be sorted by from
 *                          the source table (specified by
 *                          <code>source_table_name</code>); e.g. 'timestamp
 *                          asc, x desc'.  The <code>order_by</code> columns do
 *                          not have to be present in <code>field_map</code>.
 *                          The default value is ''.
 *                                  <li> 'update_on_existing_pk': Specifies the
 *                          record collision policy for inserting the source
 *                          table records (specified by
 *                          <code>source_table_name</code>) into the target
 *                          table (specified by <code>table_name</code>) table
 *                          with a <a
 *                          href="../../concepts/tables.html#primary-keys"
 *                          target="_top">primary key</a>.  If set to
 *                          <code>true</code>, any existing target table record
 *                          with primary key values that match those of a
 *                          source table record being inserted will be replaced
 *                          by that new record.  If set to <code>false</code>,
 *                          any existing target table record with primary key
 *                          values that match those of a source table record
 *                          being inserted will remain unchanged and the new
 *                          record discarded.  If the specified table does not
 *                          have a primary key, then this option is ignored.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'truncate_strings': If set to
 *                          <code>true</code>, it allows inserting unrestricted
 *                          length strings into charN string columns by
 *                          truncating the unrestricted length strings to fit.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.append_records = function(table_name, source_table_name, field_map, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.append_records(table_name, source_table_name, field_map, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        source_table_name: source_table_name,
        field_map: field_map,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/append/records", actual_request, callback);
};

/**
 * Clears (drops) one or all tables in the database cluster. The operation is
 * synchronous meaning that the table will be cleared before the function
 * returns. The response payload returns the status of the operation along with
 * the name of the table that was cleared.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: (request.table_name !== undefined && request.table_name !== null) ? request.table_name : "",
        authorization: (request.authorization !== undefined && request.authorization !== null) ? request.authorization : "",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/clear/table", actual_request, callback);
};

/**
 * Clears (drops) one or all tables in the database cluster. The operation is
 * synchronous meaning that the table will be cleared before the function
 * returns. The response payload returns the status of the operation along with
 * the name of the table that was cleared.
 *
 * @param {String} table_name  Name of the table to be cleared. Must be an
 *                             existing table. Empty string clears all
 *                             available tables, though this behavior is be
 *                             prevented by default via gpudb.conf parameter
 *                             'disable_clear_all'.
 * @param {String} authorization  No longer used. User can pass an empty
 *                                string.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'no_error_if_not_exists': If
 *                          <code>true</code> and if the table specified in
 *                          <code>table_name</code> does not exist no error is
 *                          returned. If <code>false</code> and if the table
 *                          specified in <code>table_name</code> does not exist
 *                          then an error is returned.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_table = function(table_name, authorization, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_table(table_name, authorization, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: (table_name !== undefined && table_name !== null) ? table_name : "",
        authorization: (authorization !== undefined && authorization !== null) ? authorization : "",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/clear/table", actual_request, callback);
};

/**
 * Deactivates a table monitor previously created with
 * {@linkcode GPUdb#create_table_monitor}.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_table_monitor_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_table_monitor_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        topic_id: request.topic_id,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/clear/tablemonitor", actual_request, callback);
};

/**
 * Deactivates a table monitor previously created with
 * {@linkcode GPUdb#create_table_monitor}.
 *
 * @param {String} topic_id  The topic ID returned by
 *                           {@linkcode GPUdb#create_table_monitor}.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_table_monitor = function(topic_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_table_monitor(topic_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        topic_id: topic_id,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/clear/tablemonitor", actual_request, callback);
};

/**
 * Clears or cancels the trigger identified by the specified handle. The output
 * returns the handle of the trigger cleared as well as indicating success or
 * failure of the trigger deactivation.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_trigger_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_trigger_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        trigger_id: request.trigger_id,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/clear/trigger", actual_request, callback);
};

/**
 * Clears or cancels the trigger identified by the specified handle. The output
 * returns the handle of the trigger cleared as well as indicating success or
 * failure of the trigger deactivation.
 *
 * @param {String} trigger_id  ID for the trigger to be deactivated.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.clear_trigger = function(trigger_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.clear_trigger(trigger_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        trigger_id: trigger_id,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/clear/trigger", actual_request, callback);
};

/**
 * Create a job which will run asynchronously. The response returns a job ID,
 * which can be used to query the status and result of the job. The status and
 * the result of the job upon completion can be requested by
 * {@linkcode GPUdb#get_job}.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_job_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_job_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        endpoint: request.endpoint,
        request_encoding: (request.request_encoding !== undefined && request.request_encoding !== null) ? request.request_encoding : "binary",
        data: request.data,
        data_str: request.data_str,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/job", actual_request, callback);
};

/**
 * Create a job which will run asynchronously. The response returns a job ID,
 * which can be used to query the status and result of the job. The status and
 * the result of the job upon completion can be requested by
 * {@linkcode GPUdb#get_job}.
 *
 * @param {String} endpoint  Indicates which endpoint to execute, e.g.
 *                           '/alter/table'.
 * @param {String} request_encoding  The encoding of the request payload for
 *                                   the job.
 *                                   Supported values:
 *                                   <ul>
 *                                           <li> 'binary'
 *                                           <li> 'json'
 *                                           <li> 'snappy'
 *                                   </ul>
 *                                   The default value is 'binary'.
 * @param {String} data  Binary-encoded payload for the job to be run
 *                       asynchronously.  The payload must contain the relevant
 *                       input parameters for the endpoint indicated in
 *                       <code>endpoint</code>.  Please see the documentation
 *                       for the appropriate endpoint to see what values must
 *                       (or can) be specified.  If this parameter is used,
 *                       then <code>request_encoding</code> must be
 *                       <code>binary</code> or <code>snappy</code>.
 * @param {String} data_str  JSON-encoded payload for the job to be run
 *                           asynchronously.  The payload must contain the
 *                           relevant input parameters for the endpoint
 *                           indicated in <code>endpoint</code>.  Please see
 *                           the documentation for the appropriate endpoint to
 *                           see what values must (or can) be specified.  If
 *                           this parameter is used, then
 *                           <code>request_encoding</code> must be
 *                           <code>json</code>.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_job = function(endpoint, request_encoding, data, data_str, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_job(endpoint, request_encoding, data, data_str, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        endpoint: endpoint,
        request_encoding: (request_encoding !== undefined && request_encoding !== null) ? request_encoding : "binary",
        data: data,
        data_str: data_str,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/job", actual_request, callback);
};

/**
 * Creates a table that is the result of a SQL JOIN.
 * <p>
 * For join details and examples see: <a href="../../concepts/joins.html"
 * target="_top">Joins</a>.  For limitations, see <a
 * href="../../concepts/joins.html#limitations-cautions" target="_top">Join
 * Limitations and Cautions</a>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_join_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_join_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        join_table_name: request.join_table_name,
        table_names: request.table_names,
        column_names: request.column_names,
        expressions: (request.expressions !== undefined && request.expressions !== null) ? request.expressions : [],
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/jointable", actual_request, callback);
};

/**
 * Creates a table that is the result of a SQL JOIN.
 * <p>
 * For join details and examples see: <a href="../../concepts/joins.html"
 * target="_top">Joins</a>.  For limitations, see <a
 * href="../../concepts/joins.html#limitations-cautions" target="_top">Join
 * Limitations and Cautions</a>.
 *
 * @param {String} join_table_name  Name of the join table to be created.  Has
 *                                  the same naming restrictions as <a
 *                                  href="../../concepts/tables.html"
 *                                  target="_top">tables</a>.
 * @param {String[]} table_names  The list of table names composing the join.
 *                                Corresponds to a SQL statement FROM clause.
 * @param {String[]} column_names  List of member table columns or column
 *                                 expressions to be included in the join.
 *                                 Columns can be prefixed with
 *                                 'table_id.column_name', where 'table_id' is
 *                                 the table name or alias.  Columns can be
 *                                 aliased via the syntax 'column_name as
 *                                 alias'. Wild cards '*' can be used to
 *                                 include all columns across member tables or
 *                                 'table_id.*' for all of a single table's
 *                                 columns.  Columns and column expressions
 *                                 composing the join must be uniquely named or
 *                                 aliased--therefore, the '*' wild card cannot
 *                                 be used if column names aren't unique across
 *                                 all tables.
 * @param {String[]} expressions  An optional list of expressions to combine
 *                                and filter the joined tables.  Corresponds to
 *                                a SQL statement WHERE clause. For details
 *                                see: <a
 *                                href="../../concepts/expressions.html"
 *                                target="_top">expressions</a>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the join. If the
 *                          collection provided is non-existent, the collection
 *                          will be automatically created. If empty, then the
 *                          join will be at the top level.  The default value
 *                          is ''.
 *                                  <li> 'max_query_dimensions': The maximum
 *                          number of tables in a join that can be accessed by
 *                          a query and are not equated by a foreign-key to
 *                          primary-key equality predicate
 *                                  <li> 'optimize_lookups': Use more memory to
 *                          speed up the joining of tables.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'refresh_method': Method by which the
 *                          join can be refreshed when the data in underlying
 *                          member tables have changed.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'manual': refresh only occurs when
 *                          manually requested by calling this endpoint with
 *                          refresh option set to <code>refresh</code> or
 *                          <code>full_refresh</code>
 *                                  <li> 'on_query': incrementally refresh
 *                          (refresh just those records added) whenever a new
 *                          query is issued and new data is inserted into the
 *                          base table.  A full refresh of all the records
 *                          occurs when a new query is issued and there have
 *                          been inserts to any non-base-tables since the last
 *                          query.  <a href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> will be set to not expire;
 *                          any <code>ttl</code> specified will be ignored.
 *                                  <li> 'on_insert': incrementally refresh
 *                          (refresh just those records added) whenever new
 *                          data is inserted into a base table.  A full refresh
 *                          of all the records occurs when a new query is
 *                          issued and there have been inserts to any
 *                          non-base-tables since the last query.  <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> will be set to not expire;
 *                          any <code>ttl</code> specified will be ignored.
 *                          </ul>
 *                          The default value is 'manual'.
 *                                  <li> 'refresh': Do a manual refresh of the
 *                          join if it exists - throws an error otherwise
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'no_refresh': don't refresh
 *                                  <li> 'refresh': incrementally refresh
 *                          (refresh just those records added) if new data has
 *                          been inserted into the base table.  A full refresh
 *                          of all the records occurs if there have been
 *                          inserts to any non-base-tables since the last
 *                          refresh
 *                                  <li> 'full_refresh': always refresh even if
 *                          no new records have been added.  Only refresh
 *                          method guaranteed to do a full refresh (refresh all
 *                          the records) if a delete or update has occurred
 *                          since the last refresh.
 *                          </ul>
 *                          The default value is 'no_refresh'.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the join table specified
 *                          in <code>join_table_name</code>.  Ignored if
 *                          <code>refresh_method</code> is either
 *                          <code>on_insert</code> or <code>on_query</code>.
 *                                  <li> 'view_id': view this projection is
 *                          part of.  The default value is ''.
 *                                  <li> 'no_count': return a count of 0 for
 *                          the join table for logging and for show_table.
 *                          optimization needed for large overlapped equi-join
 *                          stencils.  The default value is 'false'.
 *                                  <li> 'chunk_size': Maximum size of a
 *                          joined-chunk for this table. Defaults to the
 *                          gpudb.conf file chunk size
 *                                  <li> 'allow_right_primary_key_join': When
 *                          true allows right joins from a key to a primary key
 *                          to be done as primary key joins.  Such a join table
 *                          cannot be joined to other join tables.  When false
 *                          the right join shall be done as an equi-join.  The
 *                          default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_join_table = function(join_table_name, table_names, column_names, expressions, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_join_table(join_table_name, table_names, column_names, expressions, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        join_table_name: join_table_name,
        table_names: table_names,
        column_names: column_names,
        expressions: (expressions !== undefined && expressions !== null) ? expressions : [],
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/jointable", actual_request, callback);
};

/**
 * Initiates the process of creating a materialized view, reserving the view's
 * name to prevent other views or tables from being created with that name.
 * <p>
 * For materialized view details and examples, see <a
 * href="../../concepts/materialized_views.html" target="_top">Materialized
 * Views</a>.
 * <p>
 * The response contains <code>view_id</code>, which is used to tag each
 * subsequent operation (projection, union, aggregation, filter, or join) that
 * will compose the view.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_materialized_view_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_materialized_view_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/materializedview", actual_request, callback);
};

/**
 * Initiates the process of creating a materialized view, reserving the view's
 * name to prevent other views or tables from being created with that name.
 * <p>
 * For materialized view details and examples, see <a
 * href="../../concepts/materialized_views.html" target="_top">Materialized
 * Views</a>.
 * <p>
 * The response contains <code>view_id</code>, which is used to tag each
 * subsequent operation (projection, union, aggregation, filter, or join) that
 * will compose the view.
 *
 * @param {String} table_name  Name of the table to be created that is the
 *                             top-level table of the materialized view.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created table will be a
 *                          top-level table.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>table_name</code>.
 *                                  <li> 'persist': If <code>true</code>, then
 *                          the materialized view specified in
 *                          <code>table_name</code> will be persisted and will
 *                          not expire unless a <code>ttl</code> is specified.
 *                          If <code>false</code>, then the materialized view
 *                          will be an in-memory table and will expire unless a
 *                          <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'refresh_method': Method by which the
 *                          join can be refreshed when the data in underlying
 *                          member tables have changed.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'manual': Refresh only occurs when
 *                          manually requested by calling
 *                          {@linkcode GPUdb#alter_table} with an 'action' of
 *                          'refresh'
 *                                  <li> 'on_query': For future use.
 *                                  <li> 'on_change': If possible,
 *                          incrementally refresh (refresh just those records
 *                          added) whenever an insert, update, delete or
 *                          refresh of input table is done.  A full refresh is
 *                          done if an incremental refresh is not possible.
 *                                  <li> 'periodic': Refresh table periodically
 *                          at rate specified by <code>refresh_period</code>
 *                          </ul>
 *                          The default value is 'manual'.
 *                                  <li> 'refresh_period': When
 *                          <code>refresh_method</code> is
 *                          <code>periodic</code>, specifies the period in
 *                          seconds at which refresh occurs
 *                                  <li> 'refresh_start_time': When
 *                          <code>refresh_method</code> is
 *                          <code>periodic</code>, specifies the first time at
 *                          which a refresh is to be done.  Value is a datetime
 *                          string with format 'YYYY-MM-DD HH:MM:SS'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_materialized_view = function(table_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_materialized_view(table_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/materializedview", actual_request, callback);
};

/**
 * Creates an instance (proc) of the user-defined function (UDF) specified by
 * the given command, options, and files, and makes it available for execution.
 * For details on UDFs, see: <a href="../../concepts/udf.html"
 * target="_top">User-Defined Functions</a>
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: request.proc_name,
        execution_mode: (request.execution_mode !== undefined && request.execution_mode !== null) ? request.execution_mode : "distributed",
        files: (request.files !== undefined && request.files !== null) ? request.files : {},
        command: (request.command !== undefined && request.command !== null) ? request.command : "",
        args: (request.args !== undefined && request.args !== null) ? request.args : [],
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/proc", actual_request, callback);
};

/**
 * Creates an instance (proc) of the user-defined function (UDF) specified by
 * the given command, options, and files, and makes it available for execution.
 * For details on UDFs, see: <a href="../../concepts/udf.html"
 * target="_top">User-Defined Functions</a>
 *
 * @param {String} proc_name  Name of the proc to be created. Must not be the
 *                            name of a currently existing proc.
 * @param {String} execution_mode  The execution mode of the proc.
 *                                 Supported values:
 *                                 <ul>
 *                                         <li> 'distributed': Input table data
 *                                 will be divided into data segments that are
 *                                 distributed across all nodes in the cluster,
 *                                 and the proc command will be invoked once
 *                                 per data segment in parallel. Output table
 *                                 data from each invocation will be saved to
 *                                 the same node as the corresponding input
 *                                 data.
 *                                         <li> 'nondistributed': The proc
 *                                 command will be invoked only once per
 *                                 execution, and will not have access to any
 *                                 input or output table data.
 *                                 </ul>
 *                                 The default value is 'distributed'.
 * @param {Object} files  A map of the files that make up the proc. The keys of
 *                        the map are file names, and the values are the binary
 *                        contents of the files. The file names may include
 *                        subdirectory names (e.g. 'subdir/file') but must not
 *                        resolve to a directory above the root for the proc.
 * @param {String} command  The command (excluding arguments) that will be
 *                          invoked when the proc is executed. It will be
 *                          invoked from the directory containing the proc
 *                          <code>files</code> and may be any command that can
 *                          be resolved from that directory. It need not refer
 *                          to a file actually in that directory; for example,
 *                          it could be 'java' if the proc is a Java
 *                          application; however, any necessary external
 *                          programs must be preinstalled on every database
 *                          node. If the command refers to a file in that
 *                          directory, it must be preceded with './' as per
 *                          Linux convention. If not specified, and exactly one
 *                          file is provided in <code>files</code>, that file
 *                          will be invoked.
 * @param {String[]} args  An array of command-line arguments that will be
 *                         passed to <code>command</code> when the proc is
 *                         executed.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'max_concurrency_per_node': The
 *                          maximum number of concurrent instances of the proc
 *                          that will be executed per node. 0 allows unlimited
 *                          concurrency.  The default value is '0'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_proc = function(proc_name, execution_mode, files, command, args, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_proc(proc_name, execution_mode, files, command, args, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: proc_name,
        execution_mode: (execution_mode !== undefined && execution_mode !== null) ? execution_mode : "distributed",
        files: (files !== undefined && files !== null) ? files : {},
        command: (command !== undefined && command !== null) ? command : "",
        args: (args !== undefined && args !== null) ? args : [],
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/proc", actual_request, callback);
};

/**
 * Creates a new <a href="../../concepts/projections.html"
 * target="_top">projection</a> of an existing table. A projection represents a
 * subset of the columns (potentially including derived columns) of a table.
 * <p>
 * For projection details and examples, see <a
 * href="../../concepts/projections.html" target="_top">Projections</a>.  For
 * limitations, see <a
 * href="../../concepts/projections.html#limitations-and-cautions"
 * target="_top">Projection Limitations and Cautions</a>.
 * <p>
 * <a href="../../concepts/window.html" target="_top">Window functions</a>,
 * which can perform operations like moving averages, are available through
 * this endpoint as well as {@linkcode GPUdb#get_records_by_column}.
 * <p>
 * A projection can be created with a different <a
 * href="../../concepts/tables.html#shard-keys" target="_top">shard key</a>
 * than the source table.  By specifying <code>shard_key</code>, the projection
 * will be sharded according to the specified columns, regardless of how the
 * source table is sharded.  The source table can even be unsharded or
 * replicated.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_projection_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_projection_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        projection_name: request.projection_name,
        column_names: request.column_names,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/projection", actual_request, callback);
};

/**
 * Creates a new <a href="../../concepts/projections.html"
 * target="_top">projection</a> of an existing table. A projection represents a
 * subset of the columns (potentially including derived columns) of a table.
 * <p>
 * For projection details and examples, see <a
 * href="../../concepts/projections.html" target="_top">Projections</a>.  For
 * limitations, see <a
 * href="../../concepts/projections.html#limitations-and-cautions"
 * target="_top">Projection Limitations and Cautions</a>.
 * <p>
 * <a href="../../concepts/window.html" target="_top">Window functions</a>,
 * which can perform operations like moving averages, are available through
 * this endpoint as well as {@linkcode GPUdb#get_records_by_column}.
 * <p>
 * A projection can be created with a different <a
 * href="../../concepts/tables.html#shard-keys" target="_top">shard key</a>
 * than the source table.  By specifying <code>shard_key</code>, the projection
 * will be sharded according to the specified columns, regardless of how the
 * source table is sharded.  The source table can even be unsharded or
 * replicated.
 *
 * @param {String} table_name  Name of the existing table on which the
 *                             projection is to be applied.
 * @param {String} projection_name  Name of the projection to be created. Has
 *                                  the same naming restrictions as <a
 *                                  href="../../concepts/tables.html"
 *                                  target="_top">tables</a>.
 * @param {String[]} column_names  List of columns from <code>table_name</code>
 *                                 to be included in the projection. Can
 *                                 include derived columns. Can be specified as
 *                                 aliased via the syntax 'column_name as
 *                                 alias'.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a <a
 *                          href="../../concepts/collections.html"
 *                          target="_top">collection</a> to which the
 *                          projection is to be assigned as a child. If the
 *                          collection provided is non-existent, the collection
 *                          will be automatically created. If empty, then the
 *                          projection will be at the top level.  The default
 *                          value is ''.
 *                                  <li> 'expression': An optional filter <a
 *                          href="../../concepts/expressions.html"
 *                          target="_top">expression</a> to be applied to the
 *                          source table prior to the projection.  The default
 *                          value is ''.
 *                                  <li> 'is_replicated': If <code>true</code>
 *                          then the projection will be replicated even if the
 *                          source table is not.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'limit': The number of records to
 *                          keep.  The default value is ''.
 *                                  <li> 'order_by': Comma-separated list of
 *                          the columns to be sorted by; e.g. 'timestamp asc, x
 *                          desc'.  The columns specified must be present in
 *                          <code>column_names</code>.  If any alias is given
 *                          for any column name, the alias must be used, rather
 *                          than the original column name.  The default value
 *                          is ''.
 *                                  <li> 'materialize_on_gpu': If
 *                          <code>true</code> then the columns of the
 *                          projection will be cached on the GPU.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for this table.
 *                                  <li> 'create_indexes': Comma-separated list
 *                          of columns on which to create indexes on the output
 *                          table.  The columns specified must be present in
 *                          <code>column_names</code>.  If any alias is given
 *                          for any column name, the alias must be used, rather
 *                          than the original column name.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the projection specified
 *                          in <code>projection_name</code>.
 *                                  <li> 'shard_key': Comma-separated list of
 *                          the columns to be sharded on; e.g. 'column1,
 *                          column2'.  The columns specified must be present in
 *                          <code>column_names</code>.  If any alias is given
 *                          for any column name, the alias must be used, rather
 *                          than the original column name.  The default value
 *                          is ''.
 *                                  <li> 'persist': If <code>true</code>, then
 *                          the projection specified in
 *                          <code>projection_name</code> will be persisted and
 *                          will not expire unless a <code>ttl</code> is
 *                          specified.   If <code>false</code>, then the
 *                          projection will be an in-memory table and will
 *                          expire unless a <code>ttl</code> is specified
 *                          otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'preserve_dict_encoding': If
 *                          <code>true</code>, then columns that were dict
 *                          encoded in the source table will be dict encoded in
 *                          the projection table.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'view_id': view this projection is
 *                          part of.  The default value is ''.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_projection = function(table_name, projection_name, column_names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_projection(table_name, projection_name, column_names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        projection_name: projection_name,
        column_names: column_names,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/projection", actual_request, callback);
};

/**
 * Creates a new role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_role_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_role_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/role", actual_request, callback);
};

/**
 * Creates a new role.
 *
 * @param {String} name  Name of the role to be created. Must contain only
 *                       lowercase letters, digits, and underscores, and cannot
 *                       begin with a digit. Must not be the same name as an
 *                       existing user or role.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_role = function(name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_role(name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/role", actual_request, callback);
};

/**
 * Creates a new table or collection. If a new table is being created, the type
 * of the table is given by <code>type_id</code>, which must the be the ID of a
 * currently registered type (i.e. one created via
 * {@linkcode GPUdb#create_type}). The table will be created inside a
 * collection if the option <code>collection_name</code> is specified. If that
 * collection does not already exist, it will be created.
 * <p>
 * To create a new collection, specify the name of the collection in
 * <code>table_name</code> and set the <code>is_collection</code> option to
 * <code>true</code>; <code>type_id</code> will be ignored.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        type_id: request.type_id,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/table", actual_request, callback);
};

/**
 * Creates a new table or collection. If a new table is being created, the type
 * of the table is given by <code>type_id</code>, which must the be the ID of a
 * currently registered type (i.e. one created via
 * {@linkcode GPUdb#create_type}). The table will be created inside a
 * collection if the option <code>collection_name</code> is specified. If that
 * collection does not already exist, it will be created.
 * <p>
 * To create a new collection, specify the name of the collection in
 * <code>table_name</code> and set the <code>is_collection</code> option to
 * <code>true</code>; <code>type_id</code> will be ignored.
 *
 * @param {String} table_name  Name of the table to be created. Error for
 *                             requests with existing table of the same name
 *                             and type id may be suppressed by using the
 *                             <code>no_error_if_exists</code> option.  See <a
 *                             href="../../concepts/tables.html"
 *                             target="_top">Tables</a> for naming
 *                             restrictions.
 * @param {String} type_id  ID of a currently registered type. All objects
 *                          added to the newly created table will be of this
 *                          type.  Ignored if <code>is_collection</code> is
 *                          <code>true</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'no_error_if_exists': If
 *                          <code>true</code>, prevents an error from occurring
 *                          if the table already exists and is of the given
 *                          type.  If a table with the same ID but a different
 *                          type exists, it is still an error.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          table. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created table will be a
 *                          top-level table.
 *                                  <li> 'is_collection': Indicates whether the
 *                          new table to be created will be a collection.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'disallow_homogeneous_tables': For a
 *                          collection, indicates whether the collection
 *                          prohibits containment of multiple tables of exactly
 *                          the same data type.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'is_replicated': For a table,
 *                          indicates the <a
 *                          href="../../concepts/tables.html#distribution"
 *                          target="_top">distribution scheme</a> for the
 *                          table's data.  If true, the table will be <a
 *                          href="../../concepts/tables.html#replication"
 *                          target="_top">replicated</a>.  If false, the table
 *                          will be <a
 *                          href="../../concepts/tables.html#sharding"
 *                          target="_top">sharded</a> according to the <a
 *                          href="../../concepts/tables.html#shard-keys"
 *                          target="_top">shard key</a> specified in the given
 *                          <code>type_id</code>, or <a
 *                          href="../../concepts/tables.html#random-sharding"
 *                          target="_top">randomly sharded</a>, if no shard key
 *                          is specified.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'foreign_keys': Semicolon-separated
 *                          list of <a
 *                          href="../../concepts/tables.html#foreign-keys"
 *                          target="_top">foreign keys</a>, of the format
 *                          '(source_column_name [, ...]) references
 *                          target_table_name(primary_key_column_name [, ...])
 *                          [as foreign_key_name]'.
 *                                  <li> 'foreign_shard_key': Foreign shard key
 *                          of the format 'source_column references
 *                          shard_by_column from
 *                          target_table(primary_key_column)'
 *                                  <li> 'ttl': For a table, sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>table_name</code>.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for this table.
 *                                  <li> 'is_result_table': For a table,
 *                          indicates whether the table is an in-memory table.
 *                          A result table cannot contain store_only,
 *                          text_search, or string columns (charN columns are
 *                          acceptable), and it will not be retained if the
 *                          server is restarted.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_table = function(table_name, type_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_table(table_name, type_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        type_id: type_id,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/table", actual_request, callback);
};

/**
 * Creates a monitor that watches for new records inserted into a particular
 * table (identified by <code>table_name</code>) and forwards copies to
 * subscribers via ZMQ. After this call completes, subscribe to the returned
 * <code>topic_id</code> on the ZMQ table monitor port (default 9002). Each
 * time an insert operation on the table completes, a multipart message is
 * published for that topic; the first part contains only the topic ID, and
 * each subsequent part contains one binary-encoded Avro object that was
 * inserted. The monitor will continue to run (regardless of whether or not
 * there are any subscribers) until deactivated with
 * {@linkcode GPUdb#clear_table_monitor}.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_table_monitor_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_table_monitor_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/tablemonitor", actual_request, callback);
};

/**
 * Creates a monitor that watches for new records inserted into a particular
 * table (identified by <code>table_name</code>) and forwards copies to
 * subscribers via ZMQ. After this call completes, subscribe to the returned
 * <code>topic_id</code> on the ZMQ table monitor port (default 9002). Each
 * time an insert operation on the table completes, a multipart message is
 * published for that topic; the first part contains only the topic ID, and
 * each subsequent part contains one binary-encoded Avro object that was
 * inserted. The monitor will continue to run (regardless of whether or not
 * there are any subscribers) until deactivated with
 * {@linkcode GPUdb#clear_table_monitor}.
 *
 * @param {String} table_name  Name of the table to monitor. Must not refer to
 *                             a collection.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_table_monitor = function(table_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_table_monitor(table_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/tablemonitor", actual_request, callback);
};

/**
 * Sets up an area trigger mechanism for two column_names for one or more
 * tables. (This function is essentially the two-dimensional version of
 * {@linkcode GPUdb#create_trigger_by_range}.) Once the trigger has been
 * activated, any record added to the listed tables(s) via
 * {@linkcode GPUdb#insert_records} with the chosen columns' values falling
 * within the specified region will trip the trigger. All such records will be
 * queued at the trigger port (by default '9001' but able to be retrieved via
 * {@linkcode GPUdb#show_system_status}) for any listening client to collect.
 * Active triggers can be cancelled by using the
 * {@linkcode GPUdb#clear_trigger} endpoint or by clearing all relevant
 * tables.
 * <p>
 * The output returns the trigger handle as well as indicating success or
 * failure of the trigger activation.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_trigger_by_area_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_trigger_by_area_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        request_id: request.request_id,
        table_names: request.table_names,
        x_column_name: request.x_column_name,
        x_vector: request.x_vector,
        y_column_name: request.y_column_name,
        y_vector: request.y_vector,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/trigger/byarea", actual_request, callback);
};

/**
 * Sets up an area trigger mechanism for two column_names for one or more
 * tables. (This function is essentially the two-dimensional version of
 * {@linkcode GPUdb#create_trigger_by_range}.) Once the trigger has been
 * activated, any record added to the listed tables(s) via
 * {@linkcode GPUdb#insert_records} with the chosen columns' values falling
 * within the specified region will trip the trigger. All such records will be
 * queued at the trigger port (by default '9001' but able to be retrieved via
 * {@linkcode GPUdb#show_system_status}) for any listening client to collect.
 * Active triggers can be cancelled by using the
 * {@linkcode GPUdb#clear_trigger} endpoint or by clearing all relevant
 * tables.
 * <p>
 * The output returns the trigger handle as well as indicating success or
 * failure of the trigger activation.
 *
 * @param {String} request_id  User-created ID for the trigger. The ID can be
 *                             alphanumeric, contain symbols, and must contain
 *                             at least one character.
 * @param {String[]} table_names  Names of the tables on which the trigger will
 *                                be activated and maintained.
 * @param {String} x_column_name  Name of a numeric column on which the trigger
 *                                is activated. Usually 'x' for geospatial data
 *                                points.
 * @param {Number[]} x_vector  The respective coordinate values for the region
 *                             on which the trigger is activated. This usually
 *                             translates to the x-coordinates of a geospatial
 *                             region.
 * @param {String} y_column_name  Name of a second numeric column on which the
 *                                trigger is activated. Usually 'y' for
 *                                geospatial data points.
 * @param {Number[]} y_vector  The respective coordinate values for the region
 *                             on which the trigger is activated. This usually
 *                             translates to the y-coordinates of a geospatial
 *                             region. Must be the same length as xvals.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_trigger_by_area = function(request_id, table_names, x_column_name, x_vector, y_column_name, y_vector, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_trigger_by_area(request_id, table_names, x_column_name, x_vector, y_column_name, y_vector, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        request_id: request_id,
        table_names: table_names,
        x_column_name: x_column_name,
        x_vector: x_vector,
        y_column_name: y_column_name,
        y_vector: y_vector,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/trigger/byarea", actual_request, callback);
};

/**
 * Sets up a simple range trigger for a column_name for one or more tables.
 * Once the trigger has been activated, any record added to the listed
 * tables(s) via {@linkcode GPUdb#insert_records} with the chosen
 * column_name's value falling within the specified range will trip the
 * trigger. All such records will be queued at the trigger port (by default
 * '9001' but able to be retrieved via {@linkcode GPUdb#show_system_status})
 * for any listening client to collect. Active triggers can be cancelled by
 * using the {@linkcode GPUdb#clear_trigger} endpoint or by clearing all
 * relevant tables.
 * <p>
 * The output returns the trigger handle as well as indicating success or
 * failure of the trigger activation.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_trigger_by_range_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_trigger_by_range_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        request_id: request.request_id,
        table_names: request.table_names,
        column_name: request.column_name,
        min: request.min,
        max: request.max,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/trigger/byrange", actual_request, callback);
};

/**
 * Sets up a simple range trigger for a column_name for one or more tables.
 * Once the trigger has been activated, any record added to the listed
 * tables(s) via {@linkcode GPUdb#insert_records} with the chosen
 * column_name's value falling within the specified range will trip the
 * trigger. All such records will be queued at the trigger port (by default
 * '9001' but able to be retrieved via {@linkcode GPUdb#show_system_status})
 * for any listening client to collect. Active triggers can be cancelled by
 * using the {@linkcode GPUdb#clear_trigger} endpoint or by clearing all
 * relevant tables.
 * <p>
 * The output returns the trigger handle as well as indicating success or
 * failure of the trigger activation.
 *
 * @param {String} request_id  User-created ID for the trigger. The ID can be
 *                             alphanumeric, contain symbols, and must contain
 *                             at least one character.
 * @param {String[]} table_names  Tables on which the trigger will be active.
 * @param {String} column_name  Name of a numeric column_name on which the
 *                              trigger is activated.
 * @param {Number} min  The lower bound (inclusive) for the trigger range.
 * @param {Number} max  The upper bound (inclusive) for the trigger range.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_trigger_by_range = function(request_id, table_names, column_name, min, max, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_trigger_by_range(request_id, table_names, column_name, min, max, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        request_id: request_id,
        table_names: table_names,
        column_name: column_name,
        min: min,
        max: max,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/trigger/byrange", actual_request, callback);
};

/**
 * Creates a new type describing the layout or schema of a table. The type
 * definition is a JSON string describing the fields (i.e. columns) of the
 * type. Each field consists of a name and a data type. Supported data types
 * are: double, float, int, long, string, and bytes. In addition one or more
 * properties can be specified for each column which customize the memory usage
 * and query availability of that column.  Note that some properties are
 * mutually exclusive--i.e. they cannot be specified for any given column
 * simultaneously.  One example of mutually exclusive properties are
 * <code>data</code> and <code>store_only</code>.
 * <p>
 * A single <a href="../../concepts/tables.html#primary-keys"
 * target="_top">primary key</a> and/or single <a
 * href="../../concepts/tables.html#shard-keys" target="_top">shard key</a> can
 * be set across one or more columns. If a primary key is specified, then a
 * uniqueness constraint is enforced, in that only a single object can exist
 * with a given primary key. When [inserting]{@linkcode GPUdb#insert_records}
 * data into a table with a primary key, depending on the parameters in the
 * request, incoming objects with primary key values that match existing
 * objects will either overwrite (i.e. update) the existing object or will be
 * skipped and not added into the set.
 * <p>
 * Example of a type definition with some of the parameters::
 * <p>
 *         {"type":"record",
 *         "name":"point",
 *         "fields":[{"name":"msg_id","type":"string"},
 *                         {"name":"x","type":"double"},
 *                         {"name":"y","type":"double"},
 *                         {"name":"TIMESTAMP","type":"double"},
 *                         {"name":"source","type":"string"},
 *                         {"name":"group_id","type":"string"},
 *                         {"name":"OBJECT_ID","type":"string"}]
 *         }
 * <p>
 * Properties::
 * <p>
 *         {"group_id":["store_only"],
 *         "msg_id":["store_only","text_search"]
 *         }
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_type_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_type_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_definition: request.type_definition,
        label: request.label,
        properties: (request.properties !== undefined && request.properties !== null) ? request.properties : {},
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/type", actual_request, callback);
};

/**
 * Creates a new type describing the layout or schema of a table. The type
 * definition is a JSON string describing the fields (i.e. columns) of the
 * type. Each field consists of a name and a data type. Supported data types
 * are: double, float, int, long, string, and bytes. In addition one or more
 * properties can be specified for each column which customize the memory usage
 * and query availability of that column.  Note that some properties are
 * mutually exclusive--i.e. they cannot be specified for any given column
 * simultaneously.  One example of mutually exclusive properties are
 * <code>data</code> and <code>store_only</code>.
 * <p>
 * A single <a href="../../concepts/tables.html#primary-keys"
 * target="_top">primary key</a> and/or single <a
 * href="../../concepts/tables.html#shard-keys" target="_top">shard key</a> can
 * be set across one or more columns. If a primary key is specified, then a
 * uniqueness constraint is enforced, in that only a single object can exist
 * with a given primary key. When [inserting]{@linkcode GPUdb#insert_records}
 * data into a table with a primary key, depending on the parameters in the
 * request, incoming objects with primary key values that match existing
 * objects will either overwrite (i.e. update) the existing object or will be
 * skipped and not added into the set.
 * <p>
 * Example of a type definition with some of the parameters::
 * <p>
 *         {"type":"record",
 *         "name":"point",
 *         "fields":[{"name":"msg_id","type":"string"},
 *                         {"name":"x","type":"double"},
 *                         {"name":"y","type":"double"},
 *                         {"name":"TIMESTAMP","type":"double"},
 *                         {"name":"source","type":"string"},
 *                         {"name":"group_id","type":"string"},
 *                         {"name":"OBJECT_ID","type":"string"}]
 *         }
 * <p>
 * Properties::
 * <p>
 *         {"group_id":["store_only"],
 *         "msg_id":["store_only","text_search"]
 *         }
 *
 * @param {String} type_definition  a JSON string describing the columns of the
 *                                  type to be registered.
 * @param {String} label  A user-defined description string which can be used
 *                        to differentiate between tables and types with
 *                        otherwise identical schemas.
 * @param {Object} properties  Each key-value pair specifies the properties to
 *                             use for a given column where the key is the
 *                             column name.  All keys used must be relevant
 *                             column names for the given table.  Specifying
 *                             any property overrides the default properties
 *                             for that column (which is based on the column's
 *                             data type).
 *                             Valid values are:
 *                             <ul>
 *                                     <li> 'data': Default property for all
 *                             numeric and string type columns; makes the
 *                             column available for GPU queries.
 *                                     <li> 'text_search': Valid only for
 *                             'string' columns. Enables full text search for
 *                             string columns. Can be set independently of
 *                             <code>data</code> and <code>store_only</code>.
 *                                     <li> 'store_only': Persist the column
 *                             value but do not make it available to queries
 *                             (e.g. {@linkcode GPUdb#filter})-i.e. it is
 *                             mutually exclusive to the <code>data</code>
 *                             property. Any 'bytes' type column must have a
 *                             <code>store_only</code> property. This property
 *                             reduces system memory usage.
 *                                     <li> 'disk_optimized': Works in
 *                             conjunction with the <code>data</code> property
 *                             for string columns. This property reduces system
 *                             disk usage by disabling reverse string lookups.
 *                             Queries like {@linkcode GPUdb#filter},
 *                             {@linkcode GPUdb#filter_by_list}, and
 *                             {@linkcode GPUdb#filter_by_value} work as
 *                             usual but {@linkcode GPUdb#aggregate_unique},
 *                             {@linkcode GPUdb#aggregate_group_by} and
 *                             {@linkcode GPUdb#get_records_by_column} are
 *                             not allowed on columns with this property.
 *                                     <li> 'timestamp': Valid only for 'long'
 *                             columns. Indicates that this field represents a
 *                             timestamp and will be provided in milliseconds
 *                             since the Unix epoch: 00:00:00 Jan 1 1970.
 *                             Dates represented by a timestamp must fall
 *                             between the year 1000 and the year 2900.
 *                                     <li> 'decimal': Valid only for 'string'
 *                             columns.  It represents a SQL type NUMERIC(19,
 *                             4) data type.  There can be up to 15 digits
 *                             before the decimal point and up to four digits
 *                             in the fractional part.  The value can be
 *                             positive or negative (indicated by a minus sign
 *                             at the beginning).  This property is mutually
 *                             exclusive with the <code>text_search</code>
 *                             property.
 *                                     <li> 'date': Valid only for 'string'
 *                             columns.  Indicates that this field represents a
 *                             date and will be provided in the format
 *                             'YYYY-MM-DD'.  The allowable range is 1000-01-01
 *                             through 2900-01-01.  This property is mutually
 *                             exclusive with the <code>text_search</code>
 *                             property.
 *                                     <li> 'time': Valid only for 'string'
 *                             columns.  Indicates that this field represents a
 *                             time-of-day and will be provided in the format
 *                             'HH:MM:SS.mmm'.  The allowable range is
 *                             00:00:00.000 through 23:59:59.999.  This
 *                             property is mutually exclusive with the
 *                             <code>text_search</code> property.
 *                                     <li> 'datetime': Valid only for 'string'
 *                             columns.  Indicates that this field represents a
 *                             datetime and will be provided in the format
 *                             'YYYY-MM-DD HH:MM:SS.mmm'.  The allowable range
 *                             is 1000-01-01 00:00:00.000 through 2900-01-01
 *                             23:59:59.999.  This property is mutually
 *                             exclusive with the <code>text_search</code>
 *                             property.
 *                                     <li> 'char1': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 1 character.
 *                                     <li> 'char2': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 2 characters.
 *                                     <li> 'char4': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 4 characters.
 *                                     <li> 'char8': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 8 characters.
 *                                     <li> 'char16': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 16 characters.
 *                                     <li> 'char32': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 32 characters.
 *                                     <li> 'char64': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 64 characters.
 *                                     <li> 'char128': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 128 characters.
 *                                     <li> 'char256': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns. Strings with this property must
 *                             be no longer than 256 characters.
 *                                     <li> 'int8': This property provides
 *                             optimized memory and query performance for int
 *                             columns. Ints with this property must be between
 *                             -128 and +127 (inclusive)
 *                                     <li> 'int16': This property provides
 *                             optimized memory and query performance for int
 *                             columns. Ints with this property must be between
 *                             -32768 and +32767 (inclusive)
 *                                     <li> 'ipv4': This property provides
 *                             optimized memory, disk and query performance for
 *                             string columns representing IPv4 addresses (i.e.
 *                             192.168.1.1). Strings with this property must be
 *                             of the form: A.B.C.D where A, B, C and D are in
 *                             the range of 0-255.
 *                                     <li> 'wkt': Valid only for 'string' and
 *                             'bytes' columns. Indicates that this field
 *                             contains geospatial geometry objects in
 *                             Well-Known Text (WKT) or Well-Known Binary (WKB)
 *                             format.
 *                                     <li> 'primary_key': This property
 *                             indicates that this column will be part of (or
 *                             the entire) <a
 *                             href="../../concepts/tables.html#primary-keys"
 *                             target="_top">primary key</a>.
 *                                     <li> 'shard_key': This property
 *                             indicates that this column will be part of (or
 *                             the entire) <a
 *                             href="../../concepts/tables.html#shard-keys"
 *                             target="_top">shard key</a>.
 *                                     <li> 'nullable': This property indicates
 *                             that this column is nullable.  However, setting
 *                             this property is insufficient for making the
 *                             column nullable.  The user must declare the type
 *                             of the column as a union between its regular
 *                             type and 'null' in the avro schema for the
 *                             record type in <code>type_definition</code>.
 *                             For example, if a column is of type integer and
 *                             is nullable, then the entry for the column in
 *                             the avro schema must be: ['int', 'null'].
 *                             The C++, C#, Java, and Python APIs have built-in
 *                             convenience for bypassing setting the avro
 *                             schema by hand.  For those languages, one can
 *                             use this property as usual and not have to worry
 *                             about the avro schema for the record.
 *                                     <li> 'dict': This property indicates
 *                             that this column should be dictionary encoded.
 *                             It can only be used in conjunction with string
 *                             columns marked with a charN or date property or
 *                             with int or long columns. This property is
 *                             appropriate for columns where the cardinality
 *                             (the number of unique values) is expected to be
 *                             low, and can save a large amount of memory.
 *                                     <li> 'init_with_now': For columns with
 *                             attributes of date, time, datetime or timestamp,
 *                             at insert time, replace empty strings and
 *                             invalid timestamps with NOW()
 *                             </ul>
 *                             The default value is an empty dict ( {} ).
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_type = function(type_definition, label, properties, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_type(type_definition, label, properties, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_definition: type_definition,
        label: label,
        properties: (properties !== undefined && properties !== null) ? properties : {},
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/type", actual_request, callback);
};

/**
 * Merges data from one or more tables with comparable data types into a new
 * table.
 * <p>
 * The following merges are supported:
 * <p>
 * UNION (DISTINCT/ALL) - For data set union details and examples, see <a
 * href="../../concepts/unions.html" target="_top">Union</a>.  For limitations,
 * see <a href="../../concepts/unions.html#limitations-and-cautions"
 * target="_top">Union Limitations and Cautions</a>.
 * <p>
 * INTERSECT (DISTINCT/ALL) - For data set intersection details and examples,
 * see <a href="../../concepts/intersect.html" target="_top">Intersect</a>.
 * For limitations, see <a href="../../concepts/intersect.html#limitations"
 * target="_top">Intersect Limitations</a>.
 * <p>
 * EXCEPT (DISTINCT/ALL) - For data set subtraction details and examples, see
 * <a href="../../concepts/except.html" target="_top">Except</a>.  For
 * limitations, see <a href="../../concepts/except.html#limitations"
 * target="_top">Except Limitations</a>.
 * <p>
 * MERGE VIEWS - For a given set of <a
 * href="../../concepts/filtered_views.html" target="_top">filtered views</a>
 * on a single table, creates a single filtered view containing all of the
 * unique records across all of the given filtered data sets.
 * <p>
 * Non-charN 'string' and 'bytes' column types cannot be merged, nor can
 * columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_union_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_union_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        table_names: request.table_names,
        input_column_names: request.input_column_names,
        output_column_names: request.output_column_names,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/union", actual_request, callback);
};

/**
 * Merges data from one or more tables with comparable data types into a new
 * table.
 * <p>
 * The following merges are supported:
 * <p>
 * UNION (DISTINCT/ALL) - For data set union details and examples, see <a
 * href="../../concepts/unions.html" target="_top">Union</a>.  For limitations,
 * see <a href="../../concepts/unions.html#limitations-and-cautions"
 * target="_top">Union Limitations and Cautions</a>.
 * <p>
 * INTERSECT (DISTINCT/ALL) - For data set intersection details and examples,
 * see <a href="../../concepts/intersect.html" target="_top">Intersect</a>.
 * For limitations, see <a href="../../concepts/intersect.html#limitations"
 * target="_top">Intersect Limitations</a>.
 * <p>
 * EXCEPT (DISTINCT/ALL) - For data set subtraction details and examples, see
 * <a href="../../concepts/except.html" target="_top">Except</a>.  For
 * limitations, see <a href="../../concepts/except.html#limitations"
 * target="_top">Except Limitations</a>.
 * <p>
 * MERGE VIEWS - For a given set of <a
 * href="../../concepts/filtered_views.html" target="_top">filtered views</a>
 * on a single table, creates a single filtered view containing all of the
 * unique records across all of the given filtered data sets.
 * <p>
 * Non-charN 'string' and 'bytes' column types cannot be merged, nor can
 * columns marked as <a href="../../concepts/types.html#data-handling"
 * target="_top">store-only</a>.
 *
 * @param {String} table_name  Name of the table to be created. Has the same
 *                             naming restrictions as <a
 *                             href="../../concepts/tables.html"
 *                             target="_top">tables</a>.
 * @param {String[]} table_names  The list of table names to merge. Must
 *                                contain the names of one or more existing
 *                                tables.
 * @param {String[][]} input_column_names  The list of columns from each of the
 *                                         corresponding input tables.
 * @param {String[]} output_column_names  The list of names of the columns to
 *                                        be stored in the output table.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the output table. If
 *                          the collection provided is non-existent, the
 *                          collection will be automatically created. If empty,
 *                          the output table will be a top-level table.  The
 *                          default value is ''.
 *                                  <li> 'materialize_on_gpu': If
 *                          <code>true</code>, then the columns of the output
 *                          table will be cached on the GPU.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'mode': If <code>merge_views</code>,
 *                          then this operation will merge the provided views.
 *                          All <code>table_names</code> must be views from the
 *                          same underlying base table.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'union_all': Retains all rows from the
 *                          specified tables.
 *                                  <li> 'union': Retains all unique rows from
 *                          the specified tables (synonym for
 *                          <code>union_distinct</code>).
 *                                  <li> 'union_distinct': Retains all unique
 *                          rows from the specified tables.
 *                                  <li> 'except': Retains all unique rows from
 *                          the first table that do not appear in the second
 *                          table (only works on 2 tables).
 *                                  <li> 'except_all': Retains all
 *                          rows(including duplicates) from the first table
 *                          that do not appear in the second table (only works
 *                          on 2 tables).
 *                                  <li> 'intersect': Retains all unique rows
 *                          that appear in both of the specified tables (only
 *                          works on 2 tables).
 *                                  <li> 'intersect_all': Retains all
 *                          rows(including duplicates) that appear in both of
 *                          the specified tables (only works on 2 tables).
 *                                  <li> 'merge_views': Merge two or more views
 *                          (or views of views) of the same base data set into
 *                          a new view. If this mode is selected
 *                          <code>input_column_names</code> AND
 *                          <code>output_column_names</code> must be empty. The
 *                          resulting view would match the results of a SQL OR
 *                          operation, e.g., if filter 1 creates a view using
 *                          the expression 'x = 20' and filter 2 creates a view
 *                          using the expression 'x <= 10', then the merge
 *                          views operation creates a new view using the
 *                          expression 'x = 20 OR x <= 10'.
 *                          </ul>
 *                          The default value is 'union_all'.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for this table.
 *                                  <li> 'create_indexes': Comma-separated list
 *                          of columns on which to create indexes on the output
 *                          table.  The columns specified must be present in
 *                          <code>output_column_names</code>.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the table specified in
 *                          <code>table_name</code>.
 *                                  <li> 'persist': If <code>true</code>, then
 *                          the table specified in <code>table_name</code> will
 *                          be persisted and will not expire unless a
 *                          <code>ttl</code> is specified.   If
 *                          <code>false</code>, then the table will be an
 *                          in-memory table and will expire unless a
 *                          <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'view_id': view the output table will
 *                          be a part of.  The default value is ''.
 *                                  <li> 'force_replicated': If
 *                          <code>true</code>, then the table specified in
 *                          <code>table_name</code> will be replicated even if
 *                          the source tables are not.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_union = function(table_name, table_names, input_column_names, output_column_names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_union(table_name, table_names, input_column_names, output_column_names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        table_names: table_names,
        input_column_names: input_column_names,
        output_column_names: output_column_names,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/union", actual_request, callback);
};

/**
 * Creates a new external user (a user whose credentials are managed by an
 * external LDAP).
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_user_external_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_user_external_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/user/external", actual_request, callback);
};

/**
 * Creates a new external user (a user whose credentials are managed by an
 * external LDAP).
 *
 * @param {String} name  Name of the user to be created. Must exactly match the
 *                       user's name in the external LDAP, prefixed with a @.
 *                       Must not be the same name as an existing user.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_user_external = function(name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_user_external(name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/user/external", actual_request, callback);
};

/**
 * Creates a new internal user (a user whose credentials are managed by the
 * database system).
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_user_internal_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_user_internal_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        password: request.password,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/create/user/internal", actual_request, callback);
};

/**
 * Creates a new internal user (a user whose credentials are managed by the
 * database system).
 *
 * @param {String} name  Name of the user to be created. Must contain only
 *                       lowercase letters, digits, and underscores, and cannot
 *                       begin with a digit. Must not be the same name as an
 *                       existing user or role.
 * @param {String} password  Initial password of the user to be created. May be
 *                           an empty string for no password.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.create_user_internal = function(name, password, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.create_user_internal(name, password, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        password: password,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/create/user/internal", actual_request, callback);
};

/**
 * Deletes a proc. Any currently running instances of the proc will be killed.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: request.proc_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/delete/proc", actual_request, callback);
};

/**
 * Deletes a proc. Any currently running instances of the proc will be killed.
 *
 * @param {String} proc_name  Name of the proc to be deleted. Must be the name
 *                            of a currently existing proc.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_proc = function(proc_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_proc(proc_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: proc_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/delete/proc", actual_request, callback);
};

/**
 * Deletes record(s) matching the provided criteria from the given table. The
 * record selection criteria can either be one or more
 * <code>expressions</code> (matching multiple records), a single record
 * identified by <code>record_id</code> options, or all records when using
 * <code>delete_all_records</code>.  Note that the three selection criteria are
 * mutually exclusive.  This operation cannot be run on a collection or a view.
 * The operation is synchronous meaning that a response will not be available
 * until the request is completely processed and all the matching records are
 * deleted.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        expressions: request.expressions,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/delete/records", actual_request, callback);
};

/**
 * Deletes record(s) matching the provided criteria from the given table. The
 * record selection criteria can either be one or more
 * <code>expressions</code> (matching multiple records), a single record
 * identified by <code>record_id</code> options, or all records when using
 * <code>delete_all_records</code>.  Note that the three selection criteria are
 * mutually exclusive.  This operation cannot be run on a collection or a view.
 * The operation is synchronous meaning that a response will not be available
 * until the request is completely processed and all the matching records are
 * deleted.
 *
 * @param {String} table_name  Name of the table from which to delete records.
 *                             The set must be a currently existing table and
 *                             not a collection or a view.
 * @param {String[]} expressions  A list of the actual predicates, one for each
 *                                select; format should follow the guidelines
 *                                provided <a
 *                                href="../../concepts/expressions.html"
 *                                target="_top">here</a>. Specifying one or
 *                                more <code>expressions</code> is mutually
 *                                exclusive to specifying
 *                                <code>record_id</code> in the
 *                                <code>options</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'global_expression': An optional
 *                          global expression to reduce the search space of the
 *                          <code>expressions</code>.  The default value is ''.
 *                                  <li> 'record_id': A record ID identifying a
 *                          single record, obtained at the time of
 *                          [insertion of the record]{@linkcode GPUdb#insert_records}
 *                          or by calling
 *                          {@linkcode GPUdb#get_records_from_collection}
 *                          with the *return_record_ids* option. This option
 *                          cannot be used to delete records from <a
 *                          href="../../concepts/tables.html#replication"
 *                          target="_top">replicated</a> tables.
 *                                  <li> 'delete_all_records': If set to
 *                          <code>true</code>, all records in the table will be
 *                          deleted. If set to <code>false</code>, then the
 *                          option is effectively ignored.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_records = function(table_name, expressions, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_records(table_name, expressions, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        expressions: expressions,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/delete/records", actual_request, callback);
};

/**
 * Deletes an existing role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_role_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_role_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/delete/role", actual_request, callback);
};

/**
 * Deletes an existing role.
 *
 * @param {String} name  Name of the role to be deleted. Must be an existing
 *                       role.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_role = function(name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_role(name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/delete/role", actual_request, callback);
};

/**
 * Deletes an existing user.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_user_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_user_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/delete/user", actual_request, callback);
};

/**
 * Deletes an existing user.
 *
 * @param {String} name  Name of the user to be deleted. Must be an existing
 *                       user.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.delete_user = function(name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.delete_user(name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/delete/user", actual_request, callback);
};

/**
 * Executes a proc. This endpoint is asynchronous and does not wait for the
 * proc to complete before returning.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.execute_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.execute_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: request.proc_name,
        params: (request.params !== undefined && request.params !== null) ? request.params : {},
        bin_params: (request.bin_params !== undefined && request.bin_params !== null) ? request.bin_params : {},
        input_table_names: (request.input_table_names !== undefined && request.input_table_names !== null) ? request.input_table_names : [],
        input_column_names: (request.input_column_names !== undefined && request.input_column_names !== null) ? request.input_column_names : {},
        output_table_names: (request.output_table_names !== undefined && request.output_table_names !== null) ? request.output_table_names : [],
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/execute/proc", actual_request, callback);
};

/**
 * Executes a proc. This endpoint is asynchronous and does not wait for the
 * proc to complete before returning.
 *
 * @param {String} proc_name  Name of the proc to execute. Must be the name of
 *                            a currently existing proc.
 * @param {Object} params  A map containing named parameters to pass to the
 *                         proc. Each key/value pair specifies the name of a
 *                         parameter and its value.
 * @param {Object} bin_params  A map containing named binary parameters to pass
 *                             to the proc. Each key/value pair specifies the
 *                             name of a parameter and its value.
 * @param {String[]} input_table_names  Names of the tables containing data to
 *                                      be passed to the proc. Each name
 *                                      specified must be the name of a
 *                                      currently existing table. If no table
 *                                      names are specified, no data will be
 *                                      passed to the proc.
 * @param {Object} input_column_names  Map of table names from
 *                                     <code>input_table_names</code> to lists
 *                                     of names of columns from those tables
 *                                     that will be passed to the proc. Each
 *                                     column name specified must be the name
 *                                     of an existing column in the
 *                                     corresponding table. If a table name
 *                                     from <code>input_table_names</code> is
 *                                     not included, all columns from that
 *                                     table will be passed to the proc.
 * @param {String[]} output_table_names  Names of the tables to which output
 *                                       data from the proc will be written. If
 *                                       a specified table does not exist, it
 *                                       will automatically be created with the
 *                                       same schema as the corresponding table
 *                                       (by order) from
 *                                       <code>input_table_names</code>,
 *                                       excluding any primary and shard keys.
 *                                       If a specified table is a
 *                                       non-persistent result table, it must
 *                                       not have primary or shard keys. If no
 *                                       table names are specified, no output
 *                                       data can be returned from the proc.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'cache_input': A comma-delimited list
 *                          of table names from <code>input_table_names</code>
 *                          from which input data will be cached for use in
 *                          subsequent calls to
 *                          {@linkcode GPUdb#execute_proc} with the
 *                          <code>use_cached_input</code> option. Cached input
 *                          data will be retained until the proc status is
 *                          cleared with the
 *                          [clear_complete]{@linkcode GPUdb#show_proc_status}
 *                          option of {@linkcode GPUdb#show_proc_status} and
 *                          all proc instances using the cached data have
 *                          completed.  The default value is ''.
 *                                  <li> 'use_cached_input': A comma-delimited
 *                          list of run IDs (as returned from prior calls to
 *                          {@linkcode GPUdb#execute_proc}) of running or
 *                          completed proc instances from which input data
 *                          cached using the <code>cache_input</code> option
 *                          will be used. Cached input data will not be used
 *                          for any tables specified in
 *                          <code>input_table_names</code>, but data from all
 *                          other tables cached for the specified run IDs will
 *                          be passed to the proc. If the same table was cached
 *                          for multiple specified run IDs, the cached data
 *                          from the first run ID specified in the list that
 *                          includes that table will be used.  The default
 *                          value is ''.
 *                                  <li> 'kifs_input_dirs': A comma-delimited
 *                          list of KiFS directories whose local files will be
 *                          made directly accessible to the proc through the
 *                          API. (All KiFS files, local or not, are also
 *                          accessible through the file system below the KiFS
 *                          mount point.) Each name specified must the name of
 *                          an existing KiFS directory.  The default value is
 *                          ''.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.execute_proc = function(proc_name, params, bin_params, input_table_names, input_column_names, output_table_names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.execute_proc(proc_name, params, bin_params, input_table_names, input_column_names, output_table_names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: proc_name,
        params: (params !== undefined && params !== null) ? params : {},
        bin_params: (bin_params !== undefined && bin_params !== null) ? bin_params : {},
        input_table_names: (input_table_names !== undefined && input_table_names !== null) ? input_table_names : [],
        input_column_names: (input_column_names !== undefined && input_column_names !== null) ? input_column_names : {},
        output_table_names: (output_table_names !== undefined && output_table_names !== null) ? output_table_names : [],
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/execute/proc", actual_request, callback);
};

/**
 * Filters data based on the specified expression.  The results are stored in a
 * <a href="../../concepts/filtered_views.html" target="_top">result set</a>
 * with the given <code>view_name</code>.
 * <p>
 * For details see <a href="../../concepts/expressions.html"
 * target="_top">Expressions</a>.
 * <p>
 * The response message contains the number of points for which the expression
 * evaluated to be true, which is equivalent to the size of the result view.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        expression: request.expression,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter", actual_request, callback);
};

/**
 * Filters data based on the specified expression.  The results are stored in a
 * <a href="../../concepts/filtered_views.html" target="_top">result set</a>
 * with the given <code>view_name</code>.
 * <p>
 * For details see <a href="../../concepts/expressions.html"
 * target="_top">Expressions</a>.
 * <p>
 * The response message contains the number of points for which the expression
 * evaluated to be true, which is equivalent to the size of the result view.
 *
 * @param {String} table_name  Name of the table to filter.  This may be the ID
 *                             of a collection, table or a result set (for
 *                             chaining queries). If filtering a collection,
 *                             all child tables where the filter expression is
 *                             valid will be filtered; the filtered result
 *                             tables will then be placed in a collection
 *                             specified by <code>view_name</code>.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} expression  The select expression to filter the specified
 *                             table.  For details see <a
 *                             href="../../concepts/expressions.html"
 *                             target="_top">Expressions</a>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                                  <li> 'view_id': view this filtered-view is
 *                          part of.  The default value is ''.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the view specified in
 *                          <code>view_name</code>.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter = function(table_name, view_name, expression, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter(table_name, view_name, expression, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        expression: expression,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter", actual_request, callback);
};

/**
 * Calculates which objects from a table are within a named area of interest
 * (NAI/polygon). The operation is synchronous, meaning that a response will
 * not be returned until all the matching objects are fully available. The
 * response payload provides the count of the resulting set. A new resultant
 * set (view) which satisfies the input NAI restriction specification is
 * created with the name <code>view_name</code> passed in as part of the input.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_area_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_area_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        x_column_name: request.x_column_name,
        x_vector: request.x_vector,
        y_column_name: request.y_column_name,
        y_vector: request.y_vector,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byarea", actual_request, callback);
};

/**
 * Calculates which objects from a table are within a named area of interest
 * (NAI/polygon). The operation is synchronous, meaning that a response will
 * not be returned until all the matching objects are fully available. The
 * response payload provides the count of the resulting set. A new resultant
 * set (view) which satisfies the input NAI restriction specification is
 * created with the name <code>view_name</code> passed in as part of the input.
 *
 * @param {String} table_name  Name of the table to filter.  This may be the
 *                             name of a collection, a table or a view (when
 *                             chaining queries). If filtering a collection,
 *                             all child tables where the filter expression is
 *                             valid will be filtered; the filtered result
 *                             tables will then be placed in a collection
 *                             specified by <code>view_name</code>.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} x_column_name  Name of the column containing the x values to
 *                                be filtered.
 * @param {Number[]} x_vector  List of x coordinates of the vertices of the
 *                             polygon representing the area to be filtered.
 * @param {String} y_column_name  Name of the column containing the y values to
 *                                be filtered.
 * @param {Number[]} y_vector  List of y coordinates of the vertices of the
 *                             polygon representing the area to be filtered.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created.  If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_area = function(table_name, view_name, x_column_name, x_vector, y_column_name, y_vector, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_area(table_name, view_name, x_column_name, x_vector, y_column_name, y_vector, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        x_column_name: x_column_name,
        x_vector: x_vector,
        y_column_name: y_column_name,
        y_vector: y_vector,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byarea", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a named
 * area of interest (NAI/polygon). The operation is synchronous, meaning that a
 * response will not be returned until all the matching objects are fully
 * available. The response payload provides the count of the resulting set. A
 * new resultant set (view) which satisfies the input NAI restriction
 * specification is created with the name <code>view_name</code> passed in as
 * part of the input.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_area_geometry_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_area_geometry_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        x_vector: request.x_vector,
        y_vector: request.y_vector,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byarea/geometry", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a named
 * area of interest (NAI/polygon). The operation is synchronous, meaning that a
 * response will not be returned until all the matching objects are fully
 * available. The response payload provides the count of the resulting set. A
 * new resultant set (view) which satisfies the input NAI restriction
 * specification is created with the name <code>view_name</code> passed in as
 * part of the input.
 *
 * @param {String} table_name  Name of the table to filter.  This may be the
 *                             name of a collection, a table or a view (when
 *                             chaining queries).  If filtering a collection,
 *                             all child tables where the filter expression is
 *                             valid will be filtered; the filtered result
 *                             tables will then be placed in a collection
 *                             specified by <code>view_name</code>.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Must not be an
 *                            already existing collection, table or view.
 * @param {String} column_name  Name of the geospatial geometry column to be
 *                              filtered.
 * @param {Number[]} x_vector  List of x coordinates of the vertices of the
 *                             polygon representing the area to be filtered.
 * @param {Number[]} y_vector  List of y coordinates of the vertices of the
 *                             polygon representing the area to be filtered.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_area_geometry = function(table_name, view_name, column_name, x_vector, y_vector, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_area_geometry(table_name, view_name, column_name, x_vector, y_vector, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        x_vector: x_vector,
        y_vector: y_vector,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byarea/geometry", actual_request, callback);
};

/**
 * Calculates how many objects within the given table lie in a rectangular box.
 * The operation is synchronous, meaning that a response will not be returned
 * until all the objects are fully available. The response payload provides the
 * count of the resulting set. A new resultant set which satisfies the input
 * NAI restriction specification is also created when a <code>view_name</code>
 * is passed in as part of the input payload.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_box_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_box_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        x_column_name: request.x_column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        y_column_name: request.y_column_name,
        min_y: request.min_y,
        max_y: request.max_y,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bybox", actual_request, callback);
};

/**
 * Calculates how many objects within the given table lie in a rectangular box.
 * The operation is synchronous, meaning that a response will not be returned
 * until all the objects are fully available. The response payload provides the
 * count of the resulting set. A new resultant set which satisfies the input
 * NAI restriction specification is also created when a <code>view_name</code>
 * is passed in as part of the input payload.
 *
 * @param {String} table_name  Name of the table on which the bounding box
 *                             operation will be performed. Must be an existing
 *                             table.
 * @param {String} view_name  Optional name of the result view that will be
 *                            created containing the results of the query. Has
 *                            the same naming restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} x_column_name  Name of the column on which to perform the
 *                                bounding box query. Must be a valid numeric
 *                                column.
 * @param {Number} min_x  Lower bound for the column chosen by
 *                        <code>x_column_name</code>.  Must be less than or
 *                        equal to <code>max_x</code>.
 * @param {Number} max_x  Upper bound for <code>x_column_name</code>.  Must be
 *                        greater than or equal to <code>min_x</code>.
 * @param {String} y_column_name  Name of a column on which to perform the
 *                                bounding box query. Must be a valid numeric
 *                                column.
 * @param {Number} min_y  Lower bound for <code>y_column_name</code>. Must be
 *                        less than or equal to <code>max_y</code>.
 * @param {Number} max_y  Upper bound for <code>y_column_name</code>. Must be
 *                        greater than or equal to <code>min_y</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_box = function(table_name, view_name, x_column_name, min_x, max_x, y_column_name, min_y, max_y, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_box(table_name, view_name, x_column_name, min_x, max_x, y_column_name, min_y, max_y, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        x_column_name: x_column_name,
        min_x: min_x,
        max_x: max_x,
        y_column_name: y_column_name,
        min_y: min_y,
        max_y: max_y,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bybox", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a
 * rectangular box. The operation is synchronous, meaning that a response will
 * not be returned until all the objects are fully available. The response
 * payload provides the count of the resulting set. A new resultant set which
 * satisfies the input NAI restriction specification is also created when a
 * <code>view_name</code> is passed in as part of the input payload.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_box_geometry_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_box_geometry_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bybox/geometry", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a
 * rectangular box. The operation is synchronous, meaning that a response will
 * not be returned until all the objects are fully available. The response
 * payload provides the count of the resulting set. A new resultant set which
 * satisfies the input NAI restriction specification is also created when a
 * <code>view_name</code> is passed in as part of the input payload.
 *
 * @param {String} table_name  Name of the table on which the bounding box
 *                             operation will be performed. Must be an existing
 *                             table.
 * @param {String} view_name  Optional name of the result view that will be
 *                            created containing the results of the query. Must
 *                            not be an already existing collection, table or
 *                            view.
 * @param {String} column_name  Name of the geospatial geometry column to be
 *                              filtered.
 * @param {Number} min_x  Lower bound for the x-coordinate of the rectangular
 *                        box.  Must be less than or equal to
 *                        <code>max_x</code>.
 * @param {Number} max_x  Upper bound for the x-coordinate of the rectangular
 *                        box.  Must be greater than or equal to
 *                        <code>min_x</code>.
 * @param {Number} min_y  Lower bound for the y-coordinate of the rectangular
 *                        box. Must be less than or equal to
 *                        <code>max_y</code>.
 * @param {Number} max_y  Upper bound for the y-coordinate of the rectangular
 *                        box. Must be greater than or equal to
 *                        <code>min_y</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_box_geometry = function(table_name, view_name, column_name, min_x, max_x, min_y, max_y, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_box_geometry(table_name, view_name, column_name, min_x, max_x, min_y, max_y, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bybox/geometry", actual_request, callback);
};

/**
 * Applies a geometry filter against a geospatial geometry column in a given
 * table, collection or view. The filtering geometry is provided by
 * <code>input_wkt</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_geometry_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_geometry_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        input_wkt: (request.input_wkt !== undefined && request.input_wkt !== null) ? request.input_wkt : "",
        operation: request.operation,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bygeometry", actual_request, callback);
};

/**
 * Applies a geometry filter against a geospatial geometry column in a given
 * table, collection or view. The filtering geometry is provided by
 * <code>input_wkt</code>.
 *
 * @param {String} table_name  Name of the table on which the filter by
 *                             geometry will be performed.  Must be an existing
 *                             table, collection or view containing a
 *                             geospatial geometry column.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} column_name  Name of the column to be used in the filter.
 *                              Must be a geospatial geometry column.
 * @param {String} input_wkt  A geometry in WKT format that will be used to
 *                            filter the objects in <code>table_name</code>.
 * @param {String} operation  The geometric filtering operation to perform
 *                            Supported values:
 *                            <ul>
 *                                    <li> 'contains': Matches records that
 *                            contain the given WKT in <code>input_wkt</code>,
 *                            i.e. the given WKT is within the bounds of a
 *                            record's geometry.
 *                                    <li> 'crosses': Matches records that
 *                            cross the given WKT.
 *                                    <li> 'disjoint': Matches records that are
 *                            disjoint from the given WKT.
 *                                    <li> 'equals': Matches records that are
 *                            the same as the given WKT.
 *                                    <li> 'intersects': Matches records that
 *                            intersect the given WKT.
 *                                    <li> 'overlaps': Matches records that
 *                            overlap the given WKT.
 *                                    <li> 'touches': Matches records that
 *                            touch the given WKT.
 *                                    <li> 'within': Matches records that are
 *                            within the given WKT.
 *                            </ul>
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_geometry = function(table_name, view_name, column_name, input_wkt, operation, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_geometry(table_name, view_name, column_name, input_wkt, operation, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        input_wkt: (input_wkt !== undefined && input_wkt !== null) ? input_wkt : "",
        operation: operation,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bygeometry", actual_request, callback);
};

/**
 * Calculates which records from a table have values in the given list for the
 * corresponding column. The operation is synchronous, meaning that a response
 * will not be returned until all the objects are fully available. The response
 * payload provides the count of the resulting set. A new resultant set (view)
 * which satisfies the input filter specification is also created if a
 * <code>view_name</code> is passed in as part of the request.
 * <p>
 * For example, if a type definition has the columns 'x' and 'y', then a filter
 * by list query with the column map {"x":["10.1", "2.3"], "y":["0.0", "-31.5",
 * "42.0"]} will return the count of all data points whose x and y values match
 * both in the respective x- and y-lists, e.g., "x = 10.1 and y = 0.0", "x =
 * 2.3 and y = -31.5", etc. However, a record with "x = 10.1 and y = -31.5" or
 * "x = 2.3 and y = 0.0" would not be returned because the values in the given
 * lists do not correspond.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_list_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_list_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_values_map: request.column_values_map,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bylist", actual_request, callback);
};

/**
 * Calculates which records from a table have values in the given list for the
 * corresponding column. The operation is synchronous, meaning that a response
 * will not be returned until all the objects are fully available. The response
 * payload provides the count of the resulting set. A new resultant set (view)
 * which satisfies the input filter specification is also created if a
 * <code>view_name</code> is passed in as part of the request.
 * <p>
 * For example, if a type definition has the columns 'x' and 'y', then a filter
 * by list query with the column map {"x":["10.1", "2.3"], "y":["0.0", "-31.5",
 * "42.0"]} will return the count of all data points whose x and y values match
 * both in the respective x- and y-lists, e.g., "x = 10.1 and y = 0.0", "x =
 * 2.3 and y = -31.5", etc. However, a record with "x = 10.1 and y = -31.5" or
 * "x = 2.3 and y = 0.0" would not be returned because the values in the given
 * lists do not correspond.
 *
 * @param {String} table_name  Name of the table to filter.  This may be the ID
 *                             of a collection, table or a result set (for
 *                             chaining queries). If filtering a collection,
 *                             all child tables where the filter expression is
 *                             valid will be filtered; the filtered result
 *                             tables will then be placed in a collection
 *                             specified by <code>view_name</code>.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {Object} column_values_map  List of values for the corresponding
 *                                    column in the table
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                                  <li> 'filter_mode': String indicating the
 *                          filter mode, either 'in_list' or 'not_in_list'.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'in_list': The filter will match all
 *                          items that are in the provided list(s).
 *                                  <li> 'not_in_list': The filter will match
 *                          all items that are not in the provided list(s).
 *                          </ul>
 *                          The default value is 'in_list'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_list = function(table_name, view_name, column_values_map, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_list(table_name, view_name, column_values_map, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_values_map: column_values_map,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bylist", actual_request, callback);
};

/**
 * Calculates which objects from a table lie within a circle with the given
 * radius and center point (i.e. circular NAI). The operation is synchronous,
 * meaning that a response will not be returned until all the objects are fully
 * available. The response payload provides the count of the resulting set. A
 * new resultant set (view) which satisfies the input circular NAI restriction
 * specification is also created if a <code>view_name</code> is passed in as
 * part of the request.
 * <p>
 * For track data, all track points that lie within the circle plus one point
 * on either side of the circle (if the track goes beyond the circle) will be
 * included in the result.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_radius_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_radius_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        x_column_name: request.x_column_name,
        x_center: request.x_center,
        y_column_name: request.y_column_name,
        y_center: request.y_center,
        radius: request.radius,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byradius", actual_request, callback);
};

/**
 * Calculates which objects from a table lie within a circle with the given
 * radius and center point (i.e. circular NAI). The operation is synchronous,
 * meaning that a response will not be returned until all the objects are fully
 * available. The response payload provides the count of the resulting set. A
 * new resultant set (view) which satisfies the input circular NAI restriction
 * specification is also created if a <code>view_name</code> is passed in as
 * part of the request.
 * <p>
 * For track data, all track points that lie within the circle plus one point
 * on either side of the circle (if the track goes beyond the circle) will be
 * included in the result.
 *
 * @param {String} table_name  Name of the table on which the filter by radius
 *                             operation will be performed.  Must be an
 *                             existing table.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} x_column_name  Name of the column to be used for the
 *                                x-coordinate (the longitude) of the center.
 * @param {Number} x_center  Value of the longitude of the center. Must be
 *                           within [-180.0, 180.0].
 * @param {String} y_column_name  Name of the column to be used for the
 *                                y-coordinate-the latitude-of the center.
 * @param {Number} y_center  Value of the latitude of the center. Must be
 *                           within [-90.0, 90.0].
 * @param {Number} radius  The radius of the circle within which the search
 *                         will be performed. Must be a non-zero positive
 *                         value. It is in meters; so, for example, a value of
 *                         '42000' means 42 km.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_radius = function(table_name, view_name, x_column_name, x_center, y_column_name, y_center, radius, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_radius(table_name, view_name, x_column_name, x_center, y_column_name, y_center, radius, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        x_column_name: x_column_name,
        x_center: x_center,
        y_column_name: y_column_name,
        y_center: y_center,
        radius: radius,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byradius", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a circle
 * with the given radius and center point (i.e. circular NAI). The operation is
 * synchronous, meaning that a response will not be returned until all the
 * objects are fully available. The response payload provides the count of the
 * resulting set. A new resultant set (view) which satisfies the input circular
 * NAI restriction specification is also created if a <code>view_name</code> is
 * passed in as part of the request.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_radius_geometry_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_radius_geometry_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        x_center: request.x_center,
        y_center: request.y_center,
        radius: request.radius,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byradius/geometry", actual_request, callback);
};

/**
 * Calculates which geospatial geometry objects from a table intersect a circle
 * with the given radius and center point (i.e. circular NAI). The operation is
 * synchronous, meaning that a response will not be returned until all the
 * objects are fully available. The response payload provides the count of the
 * resulting set. A new resultant set (view) which satisfies the input circular
 * NAI restriction specification is also created if a <code>view_name</code> is
 * passed in as part of the request.
 *
 * @param {String} table_name  Name of the table on which the filter by radius
 *                             operation will be performed.  Must be an
 *                             existing table.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Must not be an
 *                            already existing collection, table or view.
 * @param {String} column_name  Name of the geospatial geometry column to be
 *                              filtered.
 * @param {Number} x_center  Value of the longitude of the center. Must be
 *                           within [-180.0, 180.0].
 * @param {Number} y_center  Value of the latitude of the center. Must be
 *                           within [-90.0, 90.0].
 * @param {Number} radius  The radius of the circle within which the search
 *                         will be performed. Must be a non-zero positive
 *                         value. It is in meters; so, for example, a value of
 *                         '42000' means 42 km.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_radius_geometry = function(table_name, view_name, column_name, x_center, y_center, radius, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_radius_geometry(table_name, view_name, column_name, x_center, y_center, radius, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        x_center: x_center,
        y_center: y_center,
        radius: radius,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byradius/geometry", actual_request, callback);
};

/**
 * Calculates which objects from a table have a column that is within the given
 * bounds. An object from the table identified by <code>table_name</code> is
 * added to the view <code>view_name</code> if its column is within
 * [<code>lower_bound</code>, <code>upper_bound</code>] (inclusive). The
 * operation is synchronous. The response provides a count of the number of
 * objects which passed the bound filter.  Although this functionality can also
 * be accomplished with the standard filter function, it is more efficient.
 * <p>
 * For track objects, the count reflects how many points fall within the given
 * bounds (which may not include all the track points of any given track).
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_range_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_range_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        lower_bound: request.lower_bound,
        upper_bound: request.upper_bound,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byrange", actual_request, callback);
};

/**
 * Calculates which objects from a table have a column that is within the given
 * bounds. An object from the table identified by <code>table_name</code> is
 * added to the view <code>view_name</code> if its column is within
 * [<code>lower_bound</code>, <code>upper_bound</code>] (inclusive). The
 * operation is synchronous. The response provides a count of the number of
 * objects which passed the bound filter.  Although this functionality can also
 * be accomplished with the standard filter function, it is more efficient.
 * <p>
 * For track objects, the count reflects how many points fall within the given
 * bounds (which may not include all the track points of any given track).
 *
 * @param {String} table_name  Name of the table on which the filter by range
 *                             operation will be performed.  Must be an
 *                             existing table.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} column_name  Name of a column on which the operation would
 *                              be applied.
 * @param {Number} lower_bound  Value of the lower bound (inclusive).
 * @param {Number} upper_bound  Value of the upper bound (inclusive).
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_range = function(table_name, view_name, column_name, lower_bound, upper_bound, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_range(table_name, view_name, column_name, lower_bound, upper_bound, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        lower_bound: lower_bound,
        upper_bound: upper_bound,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byrange", actual_request, callback);
};

/**
 * Filters objects matching all points of the given track (works only on track
 * type data).  It allows users to specify a particular track to find all other
 * points in the table that fall within specified ranges-spatial and
 * temporal-of all points of the given track. Additionally, the user can
 * specify another track to see if the two intersect (or go close to each other
 * within the specified ranges). The user also has the flexibility of using
 * different metrics for the spatial distance calculation: Euclidean (flat
 * geometry) or Great Circle (spherical geometry to approximate the Earth's
 * surface distances). The filtered points are stored in a newly created result
 * set. The return value of the function is the number of points in the
 * resultant set (view).
 * <p>
 * This operation is synchronous, meaning that a response will not be returned
 * until all the objects are fully available.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_series_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_series_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        track_id: request.track_id,
        target_track_ids: request.target_track_ids,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byseries", actual_request, callback);
};

/**
 * Filters objects matching all points of the given track (works only on track
 * type data).  It allows users to specify a particular track to find all other
 * points in the table that fall within specified ranges-spatial and
 * temporal-of all points of the given track. Additionally, the user can
 * specify another track to see if the two intersect (or go close to each other
 * within the specified ranges). The user also has the flexibility of using
 * different metrics for the spatial distance calculation: Euclidean (flat
 * geometry) or Great Circle (spherical geometry to approximate the Earth's
 * surface distances). The filtered points are stored in a newly created result
 * set. The return value of the function is the number of points in the
 * resultant set (view).
 * <p>
 * This operation is synchronous, meaning that a response will not be returned
 * until all the objects are fully available.
 *
 * @param {String} table_name  Name of the table on which the filter by track
 *                             operation will be performed. Must be a currently
 *                             existing table with a <a
 *                             href="../../geospatial/geo_objects.html"
 *                             target="_top">track</a> present.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} track_id  The ID of the track which will act as the
 *                           filtering points. Must be an existing track within
 *                           the given table.
 * @param {String[]} target_track_ids  Up to one track ID to intersect with the
 *                                     "filter" track. If any provided, it must
 *                                     be an valid track ID within the given
 *                                     set.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                                  <li> 'spatial_radius': A positive number
 *                          passed as a string representing the radius of the
 *                          search area centered around each track point's
 *                          geospatial coordinates. The value is interpreted in
 *                          meters. Required parameter.
 *                                  <li> 'time_radius': A positive number
 *                          passed as a string representing the maximum
 *                          allowable time difference between the timestamps of
 *                          a filtered object and the given track's points. The
 *                          value is interpreted in seconds. Required
 *                          parameter.
 *                                  <li> 'spatial_distance_metric': A string
 *                          representing the coordinate system to use for the
 *                          spatial search criteria. Acceptable values are
 *                          'euclidean' and 'great_circle'. Optional parameter;
 *                          default is 'euclidean'.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'euclidean'
 *                                  <li> 'great_circle'
 *                          </ul>
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_series = function(table_name, view_name, track_id, target_track_ids, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_series(table_name, view_name, track_id, target_track_ids, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        track_id: track_id,
        target_track_ids: target_track_ids,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byseries", actual_request, callback);
};

/**
 * Calculates which objects from a table, collection, or view match a string
 * expression for the given string columns. The options 'case_sensitive' can be
 * used to modify the behavior for all modes except 'search'. For 'search' mode
 * details and limitations, see <a href="../../concepts/full_text_search.html"
 * target="_top">Full Text Search</a>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_string_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_string_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        expression: request.expression,
        mode: request.mode,
        column_names: request.column_names,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bystring", actual_request, callback);
};

/**
 * Calculates which objects from a table, collection, or view match a string
 * expression for the given string columns. The options 'case_sensitive' can be
 * used to modify the behavior for all modes except 'search'. For 'search' mode
 * details and limitations, see <a href="../../concepts/full_text_search.html"
 * target="_top">Full Text Search</a>.
 *
 * @param {String} table_name  Name of the table on which the filter operation
 *                             will be performed.  Must be an existing table,
 *                             collection or view.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} expression  The expression with which to filter the table.
 * @param {String} mode  The string filtering mode to apply. See below for
 *                       details.
 *                       Supported values:
 *                       <ul>
 *                               <li> 'search': Full text search query with
 *                       wildcards and boolean operators. Note that for this
 *                       mode, no column can be specified in
 *                       <code>column_names</code>; all string columns of the
 *                       table that have text search enabled will be searched.
 *                               <li> 'equals': Exact whole-string match
 *                       (accelerated).
 *                               <li> 'contains': Partial substring match (not
 *                       accelerated).  If the column is a string type
 *                       (non-charN) and the number of records is too large, it
 *                       will return 0.
 *                               <li> 'starts_with': Strings that start with
 *                       the given expression (not accelerated). If the column
 *                       is a string type (non-charN) and the number of records
 *                       is too large, it will return 0.
 *                               <li> 'regex': Full regular expression search
 *                       (not accelerated). If the column is a string type
 *                       (non-charN) and the number of records is too large, it
 *                       will return 0.
 *                       </ul>
 * @param {String[]} column_names  List of columns on which to apply the
 *                                 filter. Ignored for 'search' mode.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                                  <li> 'case_sensitive': If 'false' then
 *                          string filtering will ignore case. Does not apply
 *                          to 'search' mode.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_string = function(table_name, view_name, expression, mode, column_names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_string(table_name, view_name, expression, mode, column_names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        expression: expression,
        mode: mode,
        column_names: column_names,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bystring", actual_request, callback);
};

/**
 * Filters objects in one table based on objects in another table. The user
 * must specify matching column types from the two tables (i.e. the target
 * table from which objects will be filtered and the source table based on
 * which the filter will be created); the column names need not be the same. If
 * a <code>view_name</code> is specified, then the filtered objects will then
 * be put in a newly created view. The operation is synchronous, meaning that a
 * response will not be returned until all objects are fully available in the
 * result view. The return value contains the count (i.e. the size) of the
 * resulting view.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        column_name: request.column_name,
        source_table_name: request.source_table_name,
        source_table_column_name: request.source_table_column_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/bytable", actual_request, callback);
};

/**
 * Filters objects in one table based on objects in another table. The user
 * must specify matching column types from the two tables (i.e. the target
 * table from which objects will be filtered and the source table based on
 * which the filter will be created); the column names need not be the same. If
 * a <code>view_name</code> is specified, then the filtered objects will then
 * be put in a newly created view. The operation is synchronous, meaning that a
 * response will not be returned until all objects are fully available in the
 * result view. The return value contains the count (i.e. the size) of the
 * resulting view.
 *
 * @param {String} table_name  Name of the table whose data will be filtered.
 *                             Must be an existing table.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {String} column_name  Name of the column by whose value the data will
 *                              be filtered from the table designated by
 *                              <code>table_name</code>.
 * @param {String} source_table_name  Name of the table whose data will be
 *                                    compared against in the table called
 *                                    <code>table_name</code>. Must be an
 *                                    existing table.
 * @param {String} source_table_column_name  Name of the column in the
 *                                           <code>source_table_name</code>
 *                                           whose values will be used as the
 *                                           filter for table
 *                                           <code>table_name</code>. Must be a
 *                                           geospatial geometry column if in
 *                                           'spatial' mode; otherwise, Must
 *                                           match the type of the
 *                                           <code>column_name</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                                  <li> 'filter_mode': String indicating the
 *                          filter mode, either <code>in_table</code> or
 *                          <code>not_in_table</code>.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'in_table'
 *                                  <li> 'not_in_table'
 *                          </ul>
 *                          The default value is 'in_table'.
 *                                  <li> 'mode': Mode - should be either
 *                          <code>spatial</code> or <code>normal</code>.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'normal'
 *                                  <li> 'spatial'
 *                          </ul>
 *                          The default value is 'normal'.
 *                                  <li> 'buffer': Buffer size, in meters. Only
 *                          relevant for <code>spatial</code> mode.  The
 *                          default value is '0'.
 *                                  <li> 'buffer_method': Method used to buffer
 *                          polygons.  Only relevant for <code>spatial</code>
 *                          mode.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'normal'
 *                                  <li> 'geos': Use geos 1 edge per corner
 *                          algorithm
 *                          </ul>
 *                          The default value is 'normal'.
 *                                  <li> 'max_partition_size': Maximum number
 *                          of points in a partition. Only relevant for
 *                          <code>spatial</code> mode.  The default value is
 *                          '0'.
 *                                  <li> 'max_partition_score': Maximum number
 *                          of points * edges in a partition. Only relevant for
 *                          <code>spatial</code> mode.  The default value is
 *                          '8000000'.
 *                                  <li> 'x_column_name': Name of column
 *                          containing x value of point being filtered in
 *                          <code>spatial</code> mode.  The default value is
 *                          'x'.
 *                                  <li> 'y_column_name': Name of column
 *                          containing y value of point being filtered in
 *                          <code>spatial</code> mode.  The default value is
 *                          'y'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_table = function(table_name, view_name, column_name, source_table_name, source_table_column_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_table(table_name, view_name, column_name, source_table_name, source_table_column_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        column_name: column_name,
        source_table_name: source_table_name,
        source_table_column_name: source_table_column_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/bytable", actual_request, callback);
};

/**
 * Calculates which objects from a table has a particular value for a
 * particular column. The input parameters provide a way to specify either a
 * String or a Double valued column and a desired value for the column on which
 * the filter is performed. The operation is synchronous, meaning that a
 * response will not be returned until all the objects are fully available. The
 * response payload provides the count of the resulting set. A new result view
 * which satisfies the input filter restriction specification is also created
 * with a view name passed in as part of the input payload.  Although this
 * functionality can also be accomplished with the standard filter function, it
 * is more efficient.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_value_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_value_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        is_string: request.is_string,
        value: (request.value !== undefined && request.value !== null) ? request.value : 0,
        value_str: (request.value_str !== undefined && request.value_str !== null) ? request.value_str : "",
        column_name: request.column_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/filter/byvalue", actual_request, callback);
};

/**
 * Calculates which objects from a table has a particular value for a
 * particular column. The input parameters provide a way to specify either a
 * String or a Double valued column and a desired value for the column on which
 * the filter is performed. The operation is synchronous, meaning that a
 * response will not be returned until all the objects are fully available. The
 * response payload provides the count of the resulting set. A new result view
 * which satisfies the input filter restriction specification is also created
 * with a view name passed in as part of the input payload.  Although this
 * functionality can also be accomplished with the standard filter function, it
 * is more efficient.
 *
 * @param {String} table_name  Name of an existing table on which to perform
 *                             the calculation.
 * @param {String} view_name  If provided, then this will be the name of the
 *                            view containing the results. Has the same naming
 *                            restrictions as <a
 *                            href="../../concepts/tables.html"
 *                            target="_top">tables</a>.
 * @param {Boolean} is_string  Indicates whether the value being searched for
 *                             is string or numeric.
 * @param {Number} value  The value to search for.
 * @param {String} value_str  The string value to search for.
 * @param {String} column_name  Name of a column on which the filter by value
 *                              would be applied.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          view. If the collection provided is non-existent,
 *                          the collection will be automatically created. If
 *                          empty, then the newly created view will be
 *                          top-level.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.filter_by_value = function(table_name, view_name, is_string, value, value_str, column_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.filter_by_value(table_name, view_name, is_string, value, value_str, column_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        is_string: is_string,
        value: (value !== undefined && value !== null) ? value : 0,
        value_str: (value_str !== undefined && value_str !== null) ? value_str : "",
        column_name: column_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/filter/byvalue", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_job_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_job_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        job_id: request.job_id,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/get/job", actual_request, callback);
};

/**
 *
 * @param {Number} job_id  A unique identifier for the job whose status and
 *                         result is to be fetched.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_job = function(job_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_job(job_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        job_id: job_id,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/get/job", actual_request, callback);
};

/**
 * Retrieves records from a given table, optionally filtered by an expression
 * and/or sorted by a column. This operation can be performed on tables, views,
 * or on homogeneous collections (collections containing tables of all the same
 * type). Records can be returned encoded as binary, json or geojson.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters. Note that when paging through a table, if
 * the table (or the underlying table in case of a view) is updated (records
 * are inserted, deleted or modified) the records retrieved may differ between
 * calls based on the updates applied.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        offset: (request.offset !== undefined && request.offset !== null) ? request.offset : 0,
        limit: (request.limit !== undefined && request.limit !== null) ? request.limit : 10000,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/get/records", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.records_json);
            delete data.records_json;
        }

        callback(err, data);
    });
};

/**
 * Retrieves records from a given table, optionally filtered by an expression
 * and/or sorted by a column. This operation can be performed on tables, views,
 * or on homogeneous collections (collections containing tables of all the same
 * type). Records can be returned encoded as binary, json or geojson.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters. Note that when paging through a table, if
 * the table (or the underlying table in case of a view) is updated (records
 * are inserted, deleted or modified) the records retrieved may differ between
 * calls based on the updates applied.
 *
 * @param {String} table_name  Name of the table from which the records will be
 *                             fetched. Must be a table, view or homogeneous
 *                             collection.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned. Or END_OF_SET (-9999) to
 *                        indicate that the max number of results should be
 *                        returned.
 * @param {Object} options
 *                          <ul>
 *                                  <li> 'expression': Optional filter
 *                          expression to apply to the table.
 *                                  <li> 'fast_index_lookup': Indicates if
 *                          indexes should be used to perform the lookup for a
 *                          given expression if possible. Only applicable if
 *                          there is no sorting, the expression contains only
 *                          equivalence comparisons based on existing tables
 *                          indexes and the range of requested values is from
 *                          [0 to END_OF_SET].
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'sort_by': Optional column that the
 *                          data should be sorted by. Empty by default (i.e. no
 *                          sorting is applied).
 *                                  <li> 'sort_order': String indicating how
 *                          the returned values should be sorted - ascending or
 *                          descending. If sort_order is provided, sort_by has
 *                          to be provided.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'ascending'
 *                                  <li> 'descending'
 *                          </ul>
 *                          The default value is 'ascending'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records = function(table_name, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records(table_name, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        offset: (offset !== undefined && offset !== null) ? offset : 0,
        limit: (limit !== undefined && limit !== null) ? limit : 10000,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/get/records", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.records_json);
            delete data.records_json;
        }

        callback(err, data);
    });
};

/**
 * For a given table, retrieves the values from the requested column(s). Maps
 * of column name to the array of values as well as the column data type are
 * returned. This endpoint supports pagination with the <code>offset</code> and
 * <code>limit</code> parameters.
 * <p>
 * <a href="../../concepts/window.html" target="_top">Window functions</a>,
 * which can perform operations like moving averages, are available through
 * this endpoint as well as {@linkcode GPUdb#create_projection}.
 * <p>
 * When using pagination, if the table (or the underlying table in the case of
 * a view) is modified (records are inserted, updated, or deleted) during a
 * call to the endpoint, the records or values retrieved may differ between
 * calls based on the type of the update, e.g., the contiguity across pages
 * cannot be relied upon.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_by_column_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_by_column_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        column_names: request.column_names,
        offset: request.offset,
        limit: request.limit,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/get/records/bycolumn", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * For a given table, retrieves the values from the requested column(s). Maps
 * of column name to the array of values as well as the column data type are
 * returned. This endpoint supports pagination with the <code>offset</code> and
 * <code>limit</code> parameters.
 * <p>
 * <a href="../../concepts/window.html" target="_top">Window functions</a>,
 * which can perform operations like moving averages, are available through
 * this endpoint as well as {@linkcode GPUdb#create_projection}.
 * <p>
 * When using pagination, if the table (or the underlying table in the case of
 * a view) is modified (records are inserted, updated, or deleted) during a
 * call to the endpoint, the records or values retrieved may differ between
 * calls based on the type of the update, e.g., the contiguity across pages
 * cannot be relied upon.
 * <p>
 * The response is returned as a dynamic schema. For details see: <a
 * href="../../api/index.html#dynamic-schemas" target="_top">dynamic schemas
 * documentation</a>.
 *
 * @param {String} table_name  Name of the table on which this operation will
 *                             be performed. The table cannot be a parent set.
 * @param {String[]} column_names  The list of column values to retrieve.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned (if not provided the default
 *                        is 10000), or END_OF_SET (-9999) to indicate that the
 *                        maximum number of results allowed by the server
 *                        should be returned.
 * @param {Object} options
 *                          <ul>
 *                                  <li> 'expression': Optional filter
 *                          expression to apply to the table.
 *                                  <li> 'sort_by': Optional column(s) that the
 *                          data should be sorted by. Empty by default (i.e. no
 *                          sorting is applied).
 *                                  <li> 'sort_order': String indicating how
 *                          the returned values should be sorted - ascending or
 *                          descending. If sort_order is provided, sort_by has
 *                          to be provided.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'ascending'
 *                                  <li> 'descending'
 *                          </ul>
 *                          The default value is 'ascending'.
 *                                  <li> 'order_by': Comma-separated list of
 *                          the columns to be sorted by; e.g. 'timestamp asc, x
 *                          desc'.  The default value is ''.
 *                                  <li> 'convert_wkts_to_wkbs': If true, then
 *                          WKT string columns will be returned as WKB bytes.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_by_column = function(table_name, column_names, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_by_column(table_name, column_names, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        column_names: column_names,
        offset: offset,
        limit: limit,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/get/records/bycolumn", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.json_encoded_response);
            delete data.json_encoded_response;
        }

        callback(err, data);
    });
};

/**
 * Retrieves the complete series/track records from the given
 * <code>world_table_name</code> based on the partial track information
 * contained in the <code>table_name</code>.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters.
 * <p>
 * In contrast to {@linkcode GPUdb#get_records} this returns records grouped
 * by series/track. So if <code>offset</code> is 0 and <code>limit</code> is 5
 * this operation would return the first 5 series/tracks in
 * <code>table_name</code>. Each series/track will be returned sorted by their
 * TIMESTAMP column.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_by_series_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_by_series_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        world_table_name: request.world_table_name,
        offset: (request.offset !== undefined && request.offset !== null) ? request.offset : 0,
        limit: (request.limit !== undefined && request.limit !== null) ? request.limit : 250,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/get/records/byseries", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.list_records_json);
            delete data.list_records_json;
        }

        callback(err, data);
    });
};

/**
 * Retrieves the complete series/track records from the given
 * <code>world_table_name</code> based on the partial track information
 * contained in the <code>table_name</code>.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters.
 * <p>
 * In contrast to {@linkcode GPUdb#get_records} this returns records grouped
 * by series/track. So if <code>offset</code> is 0 and <code>limit</code> is 5
 * this operation would return the first 5 series/tracks in
 * <code>table_name</code>. Each series/track will be returned sorted by their
 * TIMESTAMP column.
 *
 * @param {String} table_name  Name of the collection/table/view for which
 *                             series/tracks will be fetched.
 * @param {String} world_table_name  Name of the table containing the complete
 *                                   series/track information to be returned
 *                                   for the tracks present in the
 *                                   <code>table_name</code>. Typically this is
 *                                   used when retrieving series/tracks from a
 *                                   view (which contains partial
 *                                   series/tracks) but the user wants to
 *                                   retrieve the entire original
 *                                   series/tracks. Can be blank.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         series/tracks to skip (useful for paging through the
 *                         results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        series/tracks to be returned. Or END_OF_SET (-9999)
 *                        to indicate that the max number of results should be
 *                        returned.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_by_series = function(table_name, world_table_name, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_by_series(table_name, world_table_name, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        world_table_name: world_table_name,
        offset: (offset !== undefined && offset !== null) ? offset : 0,
        limit: (limit !== undefined && limit !== null) ? limit : 250,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/get/records/byseries", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.list_records_json);
            delete data.list_records_json;
        }

        callback(err, data);
    });
};

/**
 * Retrieves records from a collection. The operation can optionally return the
 * record IDs which can be used in certain queries such as
 * {@linkcode GPUdb#delete_records}.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters.
 * <p>
 * Note that when using the Java API, it is not possible to retrieve records
 * from join tables using this operation.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_from_collection_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_from_collection_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        offset: (request.offset !== undefined && request.offset !== null) ? request.offset : 0,
        limit: (request.limit !== undefined && request.limit !== null) ? request.limit : 10000,
        encoding: (request.encoding !== undefined && request.encoding !== null) ? request.encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    var self = this;
    this.submit_request("/get/records/fromcollection", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.records_json);
            delete data.records_json;
        }

        callback(err, data);
    });
};

/**
 * Retrieves records from a collection. The operation can optionally return the
 * record IDs which can be used in certain queries such as
 * {@linkcode GPUdb#delete_records}.
 * <p>
 * This operation supports paging through the data via the <code>offset</code>
 * and <code>limit</code> parameters.
 * <p>
 * Note that when using the Java API, it is not possible to retrieve records
 * from join tables using this operation.
 *
 * @param {String} table_name  Name of the collection or table from which
 *                             records are to be retrieved. Must be an existing
 *                             collection or table.
 * @param {Number} offset  A positive integer indicating the number of initial
 *                         results to skip (this can be useful for paging
 *                         through the results).
 * @param {Number} limit  A positive integer indicating the maximum number of
 *                        results to be returned, or END_OF_SET (-9999) to
 *                        indicate that the max number of results should be
 *                        returned.
 * @param {Object} options
 *                          <ul>
 *                                  <li> 'return_record_ids': If 'true' then
 *                          return the internal record ID along with each
 *                          returned record. Default is 'false'.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.get_records_from_collection = function(table_name, offset, limit, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.get_records_from_collection(table_name, offset, limit, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        offset: (offset !== undefined && offset !== null) ? offset : 0,
        limit: (limit !== undefined && limit !== null) ? limit : 10000,
        encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    var self = this;
    this.submit_request("/get/records/fromcollection", actual_request, function(err, data) {
        if (err === null) {
            data.data = self.decode(data.records_json);
            delete data.records_json;
        }

        callback(err, data);
    });
};

/**
 * Grants a system-level permission to a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_permission_system_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_permission_system_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        permission: request.permission,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/grant/permission/system", actual_request, callback);
};

/**
 * Grants a system-level permission to a user or role.
 *
 * @param {String} name  Name of the user or role to which the permission will
 *                       be granted. Must be an existing user or role.
 * @param {String} permission  Permission to grant to the user or role.
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'system_admin': Full access to all
 *                             data and system functions.
 *                                     <li> 'system_write': Read and write
 *                             access to all tables.
 *                                     <li> 'system_read': Read-only access to
 *                             all tables.
 *                             </ul>
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_permission_system = function(name, permission, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_permission_system(name, permission, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        permission: permission,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/grant/permission/system", actual_request, callback);
};

/**
 * Grants a table-level permission to a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_permission_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_permission_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        permission: request.permission,
        table_name: request.table_name,
        filter_expression: (request.filter_expression !== undefined && request.filter_expression !== null) ? request.filter_expression : "",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/grant/permission/table", actual_request, callback);
};

/**
 * Grants a table-level permission to a user or role.
 *
 * @param {String} name  Name of the user or role to which the permission will
 *                       be granted. Must be an existing user or role.
 * @param {String} permission  Permission to grant to the user or role.
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'table_admin': Full read/write and
 *                             administrative access to the table.
 *                                     <li> 'table_insert': Insert access to
 *                             the table.
 *                                     <li> 'table_update': Update access to
 *                             the table.
 *                                     <li> 'table_delete': Delete access to
 *                             the table.
 *                                     <li> 'table_read': Read access to the
 *                             table.
 *                             </ul>
 * @param {String} table_name  Name of the table to which the permission grants
 *                             access. Must be an existing table, collection,
 *                             or view. If a collection, the permission also
 *                             applies to tables and views in the collection.
 * @param {String} filter_expression  Reserved for future use.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_permission_table = function(name, permission, table_name, filter_expression, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_permission_table(name, permission, table_name, filter_expression, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        permission: permission,
        table_name: table_name,
        filter_expression: (filter_expression !== undefined && filter_expression !== null) ? filter_expression : "",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/grant/permission/table", actual_request, callback);
};

/**
 * Grants membership in a role to a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_role_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_role_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        role: request.role,
        member: request.member,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/grant/role", actual_request, callback);
};

/**
 * Grants membership in a role to a user or role.
 *
 * @param {String} role  Name of the role in which membership will be granted.
 *                       Must be an existing role.
 * @param {String} member  Name of the user or role that will be granted
 *                         membership in <code>role</code>. Must be an existing
 *                         user or role.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.grant_role = function(role, member, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.grant_role(role, member, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        role: role,
        member: member,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/grant/role", actual_request, callback);
};

/**
 * Checks the existence of a proc with the given name.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: request.proc_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/has/proc", actual_request, callback);
};

/**
 * Checks the existence of a proc with the given name.
 *
 * @param {String} proc_name  Name of the proc to check for existence.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_proc = function(proc_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_proc(proc_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: proc_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/has/proc", actual_request, callback);
};

/**
 * Checks for the existence of a table with the given name.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/has/table", actual_request, callback);
};

/**
 * Checks for the existence of a table with the given name.
 *
 * @param {String} table_name  Name of the table to check for existence.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_table = function(table_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_table(table_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/has/table", actual_request, callback);
};

/**
 * Check for the existence of a type.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_type_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_type_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: request.type_id,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/has/type", actual_request, callback);
};

/**
 * Check for the existence of a type.
 *
 * @param {String} type_id  Id of the type returned in response to
 *                          {@linkcode GPUdb#create_type} request.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.has_type = function(type_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.has_type(type_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: type_id,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/has/type", actual_request, callback);
};

/**
 * Adds multiple records to the specified table. The operation is synchronous,
 * meaning that a response will not be returned until all the records are fully
 * inserted and available. The response payload provides the counts of the
 * number of records actually inserted and/or updated, and can provide the
 * unique identifier of each added record.
 * <p>
 * The <code>options</code> parameter can be used to customize this function's
 * behavior.
 * <p>
 * The <code>update_on_existing_pk</code> option specifies the record collision
 * policy for inserting into a table with a <a
 * href="../../concepts/tables.html#primary-keys" target="_top">primary
 * key</a>, but is ignored if no primary key exists.
 * <p>
 * The <code>return_record_ids</code> option indicates that the database should
 * return the unique identifiers of inserted records.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        list: (request.list !== undefined && request.list !== null) ? request.list : [],
        list_str: (request.data !== undefined && request.data !== null) ? GPUdb.encode(request.data) : [],
        list_encoding: (request.list_encoding !== undefined && request.list_encoding !== null) ? request.list_encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/insert/records", actual_request, callback);
};

/**
 * Adds multiple records to the specified table. The operation is synchronous,
 * meaning that a response will not be returned until all the records are fully
 * inserted and available. The response payload provides the counts of the
 * number of records actually inserted and/or updated, and can provide the
 * unique identifier of each added record.
 * <p>
 * The <code>options</code> parameter can be used to customize this function's
 * behavior.
 * <p>
 * The <code>update_on_existing_pk</code> option specifies the record collision
 * policy for inserting into a table with a <a
 * href="../../concepts/tables.html#primary-keys" target="_top">primary
 * key</a>, but is ignored if no primary key exists.
 * <p>
 * The <code>return_record_ids</code> option indicates that the database should
 * return the unique identifiers of inserted records.
 *
 * @param {String} table_name  Table to which the records are to be added. Must
 *                             be an existing table.
 * @param {Object[]} data  An array of JSON encoded data for the records to be
 *                         added. All records must be of the same type as that
 *                         of the table. Empty array if
 *                         <code>list_encoding</code> is <code>binary</code>.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'update_on_existing_pk': Specifies the
 *                          record collision policy for inserting into a table
 *                          with a <a
 *                          href="../../concepts/tables.html#primary-keys"
 *                          target="_top">primary key</a>.  If set to
 *                          <code>true</code>, any existing table record with
 *                          primary key values that match those of a record
 *                          being inserted will be replaced by that new record.
 *                          If set to <code>false</code>, any existing table
 *                          record with primary key values that match those of
 *                          a record being inserted will remain unchanged and
 *                          the new record discarded.  If the specified table
 *                          does not have a primary key, then this option is
 *                          ignored.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'return_record_ids': If
 *                          <code>true</code> then return the internal record
 *                          id along for each inserted record.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_records = function(table_name, data, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_records(table_name, data, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        list: [],
        list_str: GPUdb.encode(data),
        list_encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/insert/records", actual_request, callback);
};

/**
 * Generates a specified number of random records and adds them to the given
 * table. There is an optional parameter that allows the user to customize the
 * ranges of the column values. It also allows the user to specify linear
 * profiles for some or all columns in which case linear values are generated
 * rather than random ones. Only individual tables are supported for this
 * operation.
 * <p>
 * This operation is synchronous, meaning that a response will not be returned
 * until all random records are fully available.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_records_random_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_records_random_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        count: request.count,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/insert/records/random", actual_request, callback);
};

/**
 * Generates a specified number of random records and adds them to the given
 * table. There is an optional parameter that allows the user to customize the
 * ranges of the column values. It also allows the user to specify linear
 * profiles for some or all columns in which case linear values are generated
 * rather than random ones. Only individual tables are supported for this
 * operation.
 * <p>
 * This operation is synchronous, meaning that a response will not be returned
 * until all random records are fully available.
 *
 * @param {String} table_name  Table to which random records will be added.
 *                             Must be an existing table.  Also, must be an
 *                             individual table, not a collection of tables,
 *                             nor a view of a table.
 * @param {Number} count  Number of records to generate.
 * @param {Object} options  Optional parameter to pass in specifications for
 *                          the randomness of the values.  This map is
 *                          different from the *options* parameter of most
 *                          other endpoints in that it is a map of string to
 *                          map of string to doubles, while most others are
 *                          maps of string to string.  In this map, the top
 *                          level keys represent which column's parameters are
 *                          being specified, while the internal keys represents
 *                          which parameter is being specified.  These
 *                          parameters take on different meanings depending on
 *                          the type of the column.  Below follows a more
 *                          detailed description of the map:
 *                          <ul>
 *                                  <li> 'seed': If provided, the internal
 *                          random number generator will be initialized with
 *                          the given value.  The minimum is 0.  This allows
 *                          for the same set of random numbers to be generated
 *                          across invocation of this endpoint in case the user
 *                          wants to repeat the test.  Since
 *                          <code>options</code>, is a map of maps, we need an
 *                          internal map to provide the seed value.  For
 *                          example, to pass 100 as the seed value through this
 *                          parameter, you need something equivalent to:
 *                          'options' = {'seed': { 'value': 100 } }
 *                          <ul>
 *                                  <li> 'value': Pass the seed value here.
 *                          </ul>
 *                                  <li> 'all': This key indicates that the
 *                          specifications relayed in the internal map are to
 *                          be applied to all columns of the records.
 *                          <ul>
 *                                  <li> 'min': For numerical columns, the
 *                          minimum of the generated values is set to this
 *                          value.  Default is -99999.  For point, shape, and
 *                          track columns, min for numeric 'x' and 'y' columns
 *                          needs to be within [-180, 180] and [-90, 90],
 *                          respectively. The default minimum possible values
 *                          for these columns in such cases are -180.0 and
 *                          -90.0. For the 'TIMESTAMP' column, the default
 *                          minimum corresponds to Jan 1, 2010.
 *                          For string columns, the minimum length of the
 *                          randomly generated strings is set to this value
 *                          (default is 0). If both minimum and maximum are
 *                          provided, minimum must be less than or equal to
 *                          max. Value needs to be within [0, 200].
 *                          If the min is outside the accepted ranges for
 *                          strings columns and 'x' and 'y' columns for
 *                          point/shape/track, then those parameters will not
 *                          be set; however, an error will not be thrown in
 *                          such a case. It is the responsibility of the user
 *                          to use the <code>all</code> parameter judiciously.
 *                                  <li> 'max': For numerical columns, the
 *                          maximum of the generated values is set to this
 *                          value. Default is 99999. For point, shape, and
 *                          track columns, max for numeric 'x' and 'y' columns
 *                          needs to be within [-180, 180] and [-90, 90],
 *                          respectively. The default minimum possible values
 *                          for these columns in such cases are 180.0 and 90.0.
 *                          For string columns, the maximum length of the
 *                          randomly generated strings is set to this value
 *                          (default is 200). If both minimum and maximum are
 *                          provided, *max* must be greater than or equal to
 *                          *min*. Value needs to be within [0, 200].
 *                          If the *max* is outside the accepted ranges for
 *                          strings columns and 'x' and 'y' columns for
 *                          point/shape/track, then those parameters will not
 *                          be set; however, an error will not be thrown in
 *                          such a case. It is the responsibility of the user
 *                          to use the <code>all</code> parameter judiciously.
 *                                  <li> 'interval': If specified, generate
 *                          values for all columns evenly spaced with the given
 *                          interval value. If a max value is specified for a
 *                          given column the data is randomly generated between
 *                          min and max and decimated down to the interval. If
 *                          no max is provided the data is linerally generated
 *                          starting at the minimum value (instead of
 *                          generating random data). For non-decimated
 *                          string-type columns the interval value is ignored.
 *                          Instead the values are generated following the
 *                          pattern: 'attrname_creationIndex#', i.e. the column
 *                          name suffixed with an underscore and a running
 *                          counter (starting at 0). For string types with
 *                          limited size (eg char4) the prefix is dropped. No
 *                          nulls will be generated for nullable columns.
 *                                  <li> 'null_percentage': If specified, then
 *                          generate the given percentage of the count as nulls
 *                          for all nullable columns.  This option will be
 *                          ignored for non-nullable columns.  The value must
 *                          be within the range [0, 1.0].  The default value is
 *                          5% (0.05).
 *                                  <li> 'cardinality': If specified, limit the
 *                          randomly generated values to a fixed set. Not
 *                          allowed on a column with interval specified, and is
 *                          not applicable to WKT or Track-specific columns.
 *                          The value must be greater than 0. This option is
 *                          disabled by default.
 *                          </ul>
 *                                  <li> 'attr_name': Use the desired column
 *                          name in place of <code>attr_name</code>, and set
 *                          the following parameters for the column specified.
 *                          This overrides any parameter set by
 *                          <code>all</code>.
 *                          <ul>
 *                                  <li> 'min': For numerical columns, the
 *                          minimum of the generated values is set to this
 *                          value.  Default is -99999.  For point, shape, and
 *                          track columns, min for numeric 'x' and 'y' columns
 *                          needs to be within [-180, 180] and [-90, 90],
 *                          respectively. The default minimum possible values
 *                          for these columns in such cases are -180.0 and
 *                          -90.0. For the 'TIMESTAMP' column, the default
 *                          minimum corresponds to Jan 1, 2010.
 *                          For string columns, the minimum length of the
 *                          randomly generated strings is set to this value
 *                          (default is 0). If both minimum and maximum are
 *                          provided, minimum must be less than or equal to
 *                          max. Value needs to be within [0, 200].
 *                          If the min is outside the accepted ranges for
 *                          strings columns and 'x' and 'y' columns for
 *                          point/shape/track, then those parameters will not
 *                          be set; however, an error will not be thrown in
 *                          such a case. It is the responsibility of the user
 *                          to use the <code>all</code> parameter judiciously.
 *                                  <li> 'max': For numerical columns, the
 *                          maximum of the generated values is set to this
 *                          value. Default is 99999. For point, shape, and
 *                          track columns, max for numeric 'x' and 'y' columns
 *                          needs to be within [-180, 180] and [-90, 90],
 *                          respectively. The default minimum possible values
 *                          for these columns in such cases are 180.0 and 90.0.
 *                          For string columns, the maximum length of the
 *                          randomly generated strings is set to this value
 *                          (default is 200). If both minimum and maximum are
 *                          provided, *max* must be greater than or equal to
 *                          *min*. Value needs to be within [0, 200].
 *                          If the *max* is outside the accepted ranges for
 *                          strings columns and 'x' and 'y' columns for
 *                          point/shape/track, then those parameters will not
 *                          be set; however, an error will not be thrown in
 *                          such a case. It is the responsibility of the user
 *                          to use the <code>all</code> parameter judiciously.
 *                                  <li> 'interval': If specified, generate
 *                          values for all columns evenly spaced with the given
 *                          interval value. If a max value is specified for a
 *                          given column the data is randomly generated between
 *                          min and max and decimated down to the interval. If
 *                          no max is provided the data is linerally generated
 *                          starting at the minimum value (instead of
 *                          generating random data). For non-decimated
 *                          string-type columns the interval value is ignored.
 *                          Instead the values are generated following the
 *                          pattern: 'attrname_creationIndex#', i.e. the column
 *                          name suffixed with an underscore and a running
 *                          counter (starting at 0). For string types with
 *                          limited size (eg char4) the prefix is dropped. No
 *                          nulls will be generated for nullable columns.
 *                                  <li> 'null_percentage': If specified and if
 *                          this column is nullable, then generate the given
 *                          percentage of the count as nulls.  This option will
 *                          result in an error if the column is not nullable.
 *                          The value must be within the range [0, 1.0].  The
 *                          default value is 5% (0.05).
 *                                  <li> 'cardinality': If specified, limit the
 *                          randomly generated values to a fixed set. Not
 *                          allowed on a column with interval specified, and is
 *                          not applicable to WKT or Track-specific columns.
 *                          The value must be greater than 0. This option is
 *                          disabled by default.
 *                          </ul>
 *                                  <li> 'track_length': This key-map pair is
 *                          only valid for track data sets (an error is thrown
 *                          otherwise).  No nulls would be generated for
 *                          nullable columns.
 *                          <ul>
 *                                  <li> 'min': Minimum possible length for
 *                          generated series; default is 100 records per
 *                          series. Must be an integral value within the range
 *                          [1, 500]. If both min and max are specified, min
 *                          must be less than or equal to max.
 *                                  <li> 'max': Maximum possible length for
 *                          generated series; default is 500 records per
 *                          series. Must be an integral value within the range
 *                          [1, 500]. If both min and max are specified, max
 *                          must be greater than or equal to min.
 *                          </ul>
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_records_random = function(table_name, count, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_records_random(table_name, count, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        count: count,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/insert/records/random", actual_request, callback);
};

/**
 * Adds a symbol or icon (i.e. an image) to represent data points when data is
 * rendered visually. Users must provide the symbol identifier (string), a
 * format (currently supported: 'svg' and 'svg_path'), the data for the symbol,
 * and any additional optional parameter (e.g. color). To have a symbol used
 * for rendering create a table with a string column named 'SYMBOLCODE' (along
 * with 'x' or 'y' for example). Then when the table is rendered (via <a
 * href="../../api/rest/wms_rest.html" target="_top">WMS</a>) if the
 * 'dosymbology' parameter is 'true' then the value of the 'SYMBOLCODE' column
 * is used to pick the symbol displayed for each point.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_symbol_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_symbol_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        symbol_id: request.symbol_id,
        symbol_format: request.symbol_format,
        symbol_data: request.symbol_data,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/insert/symbol", actual_request, callback);
};

/**
 * Adds a symbol or icon (i.e. an image) to represent data points when data is
 * rendered visually. Users must provide the symbol identifier (string), a
 * format (currently supported: 'svg' and 'svg_path'), the data for the symbol,
 * and any additional optional parameter (e.g. color). To have a symbol used
 * for rendering create a table with a string column named 'SYMBOLCODE' (along
 * with 'x' or 'y' for example). Then when the table is rendered (via <a
 * href="../../api/rest/wms_rest.html" target="_top">WMS</a>) if the
 * 'dosymbology' parameter is 'true' then the value of the 'SYMBOLCODE' column
 * is used to pick the symbol displayed for each point.
 *
 * @param {String} symbol_id  The id of the symbol being added. This is the
 *                            same id that should be in the 'SYMBOLCODE' column
 *                            for objects using this symbol
 * @param {String} symbol_format  Specifies the symbol format. Must be either
 *                                'svg' or 'svg_path'.
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'svg'
 *                                        <li> 'svg_path'
 *                                </ul>
 * @param {String} symbol_data  The actual symbol data. If
 *                              <code>symbol_format</code> is 'svg' then this
 *                              should be the raw bytes representing an svg
 *                              file. If <code>symbol_format</code> is svg path
 *                              then this should be an svg path string, for
 *                              example:
 *                              'M25.979,12.896,5.979,12.896,5.979,19.562,25.979,19.562z'
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'color': If <code>symbol_format</code>
 *                          is 'svg' this is ignored. If
 *                          <code>symbol_format</code> is 'svg_path' then this
 *                          option specifies the color (in RRGGBB hex format)
 *                          of the path. For example, to have the path rendered
 *                          in red, used 'FF0000'. If 'color' is not provided
 *                          then '00FF00' (i.e. green) is used by default.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.insert_symbol = function(symbol_id, symbol_format, symbol_data, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.insert_symbol(symbol_id, symbol_format, symbol_data, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        symbol_id: symbol_id,
        symbol_format: symbol_format,
        symbol_data: symbol_data,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/insert/symbol", actual_request, callback);
};

/**
 * Kills a running proc instance.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.kill_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.kill_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        run_id: (request.run_id !== undefined && request.run_id !== null) ? request.run_id : "",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/kill/proc", actual_request, callback);
};

/**
 * Kills a running proc instance.
 *
 * @param {String} run_id  The run ID of the running proc instance. If the run
 *                         ID is not found or the proc instance has already
 *                         completed, this does nothing. If not specified, all
 *                         running proc instances will be killed.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.kill_proc = function(run_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.kill_proc(run_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        run_id: (run_id !== undefined && run_id !== null) ? run_id : "",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/kill/proc", actual_request, callback);
};

/**
 * Manages global access to a table's data.  By default a table has a
 * <code>lock_type</code> of <code>read_write</code>, indicating all operations
 * are permitted.  A user may request a <code>read_only</code> or a
 * <code>write_only</code> lock, after which only read or write operations,
 * respectively, are permitted on the table until the lock is removed.  When
 * <code>lock_type</code> is <code>no_access</code> then no operations are
 * permitted on the table.  The lock status can be queried by setting
 * <code>lock_type</code> to <code>status</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.lock_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.lock_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        lock_type: (request.lock_type !== undefined && request.lock_type !== null) ? request.lock_type : "status",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/lock/table", actual_request, callback);
};

/**
 * Manages global access to a table's data.  By default a table has a
 * <code>lock_type</code> of <code>read_write</code>, indicating all operations
 * are permitted.  A user may request a <code>read_only</code> or a
 * <code>write_only</code> lock, after which only read or write operations,
 * respectively, are permitted on the table until the lock is removed.  When
 * <code>lock_type</code> is <code>no_access</code> then no operations are
 * permitted on the table.  The lock status can be queried by setting
 * <code>lock_type</code> to <code>status</code>.
 *
 * @param {String} table_name  Name of the table to be locked. It must be a
 *                             currently existing table, collection, or view.
 * @param {String} lock_type  The type of lock being applied to the table.
 *                            Setting it to <code>status</code> will return the
 *                            current lock status of the table without changing
 *                            it.
 *                            Supported values:
 *                            <ul>
 *                                    <li> 'status': Show locked status
 *                                    <li> 'no_access': Allow no read/write
 *                            operations
 *                                    <li> 'read_only': Allow only read
 *                            operations
 *                                    <li> 'write_only': Allow only write
 *                            operations
 *                                    <li> 'read_write': Allow all read/write
 *                            operations
 *                            </ul>
 *                            The default value is 'status'.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.lock_table = function(table_name, lock_type, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.lock_table(table_name, lock_type, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        lock_type: (lock_type !== undefined && lock_type !== null) ? lock_type : "status",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/lock/table", actual_request, callback);
};

/**
 * Create a new empty result table (specified by <code>table_name</code>), and
 * insert all records from source tables (specified by
 * <code>source_table_names</code>) based on the field mapping information
 * (specified by <code>field_maps</code>).
 * <p>
 * For merge records details and examples, see <a
 * href="../../concepts/merge_records.html" target="_top">Merge Records</a>.
 * For limitations, see <a
 * href="../../concepts/merge_records.html#limitations-and-cautions"
 * target="_top">Merge Records Limitations and Cautions</a>.

 * The field map (specified by <code>field_maps</code>) holds the
 * user-specified maps of target table column names to source table columns.
 * The array of <code>field_maps</code> must match one-to-one with the
 * <code>source_table_names</code>, e.g., there's a map present in
 * <code>field_maps</code> for each table listed in
 * <code>source_table_names</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.merge_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.merge_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        source_table_names: request.source_table_names,
        field_maps: request.field_maps,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/merge/records", actual_request, callback);
};

/**
 * Create a new empty result table (specified by <code>table_name</code>), and
 * insert all records from source tables (specified by
 * <code>source_table_names</code>) based on the field mapping information
 * (specified by <code>field_maps</code>).
 * <p>
 * For merge records details and examples, see <a
 * href="../../concepts/merge_records.html" target="_top">Merge Records</a>.
 * For limitations, see <a
 * href="../../concepts/merge_records.html#limitations-and-cautions"
 * target="_top">Merge Records Limitations and Cautions</a>.

 * The field map (specified by <code>field_maps</code>) holds the
 * user-specified maps of target table column names to source table columns.
 * The array of <code>field_maps</code> must match one-to-one with the
 * <code>source_table_names</code>, e.g., there's a map present in
 * <code>field_maps</code> for each table listed in
 * <code>source_table_names</code>.
 *
 * @param {String} table_name  The new result table name for the records to be
 *                             merged.  Must NOT be an existing table.
 * @param {String[]} source_table_names  The list of source table names to get
 *                                       the records from. Must be existing
 *                                       table names.
 * @param {Object[]} field_maps  Contains a list of source/target column
 *                               mappings, one mapping for each source table
 *                               listed in <code>source_table_names</code>
 *                               being merged into the target table specified
 *                               by <code>table_name</code>.  Each mapping
 *                               contains the target column names (as keys)
 *                               that the data in the mapped source columns or
 *                               column <a
 *                               href="../../concepts/expressions.html"
 *                               target="_top">expressions</a> (as values) will
 *                               be merged into.  All of the source columns
 *                               being merged into a given target column must
 *                               match in type, as that type will determine the
 *                               type of the new target column.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'collection_name': Name of a
 *                          collection which is to contain the newly created
 *                          merged table specified by <code>table_name</code>.
 *                          If the collection provided is non-existent, the
 *                          collection will be automatically created. If empty,
 *                          then the newly created merged table will be a
 *                          top-level table.
 *                                  <li> 'is_replicated': Indicates the <a
 *                          href="../../concepts/tables.html#distribution"
 *                          target="_top">distribution scheme</a> for the data
 *                          of the merged table specified in
 *                          <code>table_name</code>.  If true, the table will
 *                          be <a href="../../concepts/tables.html#replication"
 *                          target="_top">replicated</a>.  If false, the table
 *                          will be <a
 *                          href="../../concepts/tables.html#random-sharding"
 *                          target="_top">randomly sharded</a>.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'ttl': Sets the <a
 *                          href="../../concepts/ttl.html"
 *                          target="_top">TTL</a> of the merged table specified
 *                          in <code>table_name</code>.
 *                                  <li> 'persist': If <code>true</code>, then
 *                          the table specified in <code>table_name</code> will
 *                          be persisted and will not expire unless a
 *                          <code>ttl</code> is specified.   If
 *                          <code>false</code>, then the table will be an
 *                          in-memory table and will expire unless a
 *                          <code>ttl</code> is specified otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'chunk_size': Indicates the chunk size
 *                          to be used for the merged table specified in
 *                          <code>table_name</code>.
 *                                  <li> 'view_id': view this result table is
 *                          part of.  The default value is ''.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.merge_records = function(table_name, source_table_names, field_maps, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.merge_records(table_name, source_table_names, field_maps, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        source_table_names: source_table_names,
        field_maps: field_maps,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/merge/records", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.admin_replace_tom_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_replace_tom_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        old_rank_tom: request.old_rank_tom,
        new_rank_tom: request.new_rank_tom
    };

    this.submit_request("/replace/tom", actual_request, callback);
};

/**
 *
 * @param {Number} old_rank_tom
 * @param {Number} new_rank_tom
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.admin_replace_tom = function(old_rank_tom, new_rank_tom, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.admin_replace_tom(old_rank_tom, new_rank_tom, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        old_rank_tom: old_rank_tom,
        new_rank_tom: new_rank_tom
    };

    this.submit_request("/replace/tom", actual_request, callback);
};

/**
 * Revokes a system-level permission from a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_permission_system_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_permission_system_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        permission: request.permission,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/revoke/permission/system", actual_request, callback);
};

/**
 * Revokes a system-level permission from a user or role.
 *
 * @param {String} name  Name of the user or role from which the permission
 *                       will be revoked. Must be an existing user or role.
 * @param {String} permission  Permission to revoke from the user or role.
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'system_admin': Full access to all
 *                             data and system functions.
 *                                     <li> 'system_write': Read and write
 *                             access to all tables.
 *                                     <li> 'system_read': Read-only access to
 *                             all tables.
 *                             </ul>
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_permission_system = function(name, permission, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_permission_system(name, permission, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        permission: permission,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/revoke/permission/system", actual_request, callback);
};

/**
 * Revokes a table-level permission from a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_permission_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_permission_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: request.name,
        permission: request.permission,
        table_name: request.table_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/revoke/permission/table", actual_request, callback);
};

/**
 * Revokes a table-level permission from a user or role.
 *
 * @param {String} name  Name of the user or role from which the permission
 *                       will be revoked. Must be an existing user or role.
 * @param {String} permission  Permission to revoke from the user or role.
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'table_admin': Full read/write and
 *                             administrative access to the table.
 *                                     <li> 'table_insert': Insert access to
 *                             the table.
 *                                     <li> 'table_update': Update access to
 *                             the table.
 *                                     <li> 'table_delete': Delete access to
 *                             the table.
 *                                     <li> 'table_read': Read access to the
 *                             table.
 *                             </ul>
 * @param {String} table_name  Name of the table to which the permission grants
 *                             access. Must be an existing table, collection,
 *                             or view.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_permission_table = function(name, permission, table_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_permission_table(name, permission, table_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        name: name,
        permission: permission,
        table_name: table_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/revoke/permission/table", actual_request, callback);
};

/**
 * Revokes membership in a role from a user or role.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_role_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_role_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        role: request.role,
        member: request.member,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/revoke/role", actual_request, callback);
};

/**
 * Revokes membership in a role from a user or role.
 *
 * @param {String} role  Name of the role in which membership will be revoked.
 *                       Must be an existing role.
 * @param {String} member  Name of the user or role that will be revoked
 *                         membership in <code>role</code>. Must be an existing
 *                         user or role.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.revoke_role = function(role, member, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.revoke_role(role, member, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        role: role,
        member: member,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/revoke/role", actual_request, callback);
};

/**
 * Shows information about a proc.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_proc_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_proc_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: (request.proc_name !== undefined && request.proc_name !== null) ? request.proc_name : "",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/proc", actual_request, callback);
};

/**
 * Shows information about a proc.
 *
 * @param {String} proc_name  Name of the proc to show information about. If
 *                            specified, must be the name of a currently
 *                            existing proc. If not specified, information
 *                            about all procs will be returned.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'include_files': If set to
 *                          <code>true</code>, the files that make up the proc
 *                          will be returned. If set to <code>false</code>, the
 *                          files will not be returned.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_proc = function(proc_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_proc(proc_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        proc_name: (proc_name !== undefined && proc_name !== null) ? proc_name : "",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/proc", actual_request, callback);
};

/**
 * Shows the statuses of running or completed proc instances. Results are
 * grouped by run ID (as returned from {@linkcode GPUdb#execute_proc}) and
 * data segment ID (each invocation of the proc command on a data segment is
 * assigned a data segment ID).
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_proc_status_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_proc_status_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        run_id: (request.run_id !== undefined && request.run_id !== null) ? request.run_id : "",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/proc/status", actual_request, callback);
};

/**
 * Shows the statuses of running or completed proc instances. Results are
 * grouped by run ID (as returned from {@linkcode GPUdb#execute_proc}) and
 * data segment ID (each invocation of the proc command on a data segment is
 * assigned a data segment ID).
 *
 * @param {String} run_id  The run ID of a specific running or completed proc
 *                         instance for which the status will be returned. If
 *                         the run ID is not found, nothing will be returned.
 *                         If not specified, the statuses of all running and
 *                         completed proc instances will be returned.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'clear_complete': If set to
 *                          <code>true</code>, if a proc instance has completed
 *                          (either successfully or unsuccessfully) then its
 *                          status will be cleared and no longer returned in
 *                          subsequent calls.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_proc_status = function(run_id, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_proc_status(run_id, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        run_id: (run_id !== undefined && run_id !== null) ? run_id : "",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/proc/status", actual_request, callback);
};

/**
 * Shows security information relating to users and/or roles. If the caller is
 * not a system administrator, only information relating to the caller and
 * their roles is returned.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_security_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_security_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        names: request.names,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/security", actual_request, callback);
};

/**
 * Shows security information relating to users and/or roles. If the caller is
 * not a system administrator, only information relating to the caller and
 * their roles is returned.
 *
 * @param {String[]} names  A list of names of users and/or roles about which
 *                          security information is requested. If none are
 *                          provided, information about all users and roles
 *                          will be returned.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_security = function(names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_security(names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        names: names,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/security", actual_request, callback);
};

/**
 * Returns server configuration and version related information to the caller.
 * The admin tool uses it to present server related information to the user.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_properties_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_properties_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/system/properties", actual_request, callback);
};

/**
 * Returns server configuration and version related information to the caller.
 * The admin tool uses it to present server related information to the user.
 *
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'properties': A list of comma
 *                          separated names of properties requested. If not
 *                          specified, all properties will be returned.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_properties = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_properties(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/system/properties", actual_request, callback);
};

/**
 * Provides server configuration and health related status to the caller. The
 * admin tool uses it to present server related information to the user.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_status_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_status_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/system/status", actual_request, callback);
};

/**
 * Provides server configuration and health related status to the caller. The
 * admin tool uses it to present server related information to the user.
 *
 * @param {Object} options  Optional parameters, currently unused.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_status = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_status(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/system/status", actual_request, callback);
};

/**
 * Returns the last 100 database requests along with the request timing and
 * internal job id. The admin tool uses it to present request timing
 * information to the user.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_timing_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_timing_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/system/timing", actual_request, callback);
};

/**
 * Returns the last 100 database requests along with the request timing and
 * internal job id. The admin tool uses it to present request timing
 * information to the user.
 *
 * @param {Object} options  Optional parameters, currently unused.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_system_timing = function(options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_system_timing(options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/system/timing", actual_request, callback);
};

/**
 * Retrieves detailed information about tables, views, and collections.
 * <p>
 * If <code>table_name</code> specifies a table or view, information specific
 * to that entity will be returned.
 * <p>
 * If <code>table_name</code> specifies a collection, the call can return
 * information about either the collection itself (setting the
 * <code>show_children</code> option to <code>false</code>) or the tables and
 * views it contains (setting <code>show_children</code> to <code>true</code>).
 * <p>
 * If <code>table_name</code> is empty, information about all collections and
 * top-level tables and views can be returned.  Note:
 * <code>show_children</code> must be set to <code>true</code>.
 * <p>
 * If <code>table_name</code> is '*', information about all tables,
 * collections, and views will be returned.  Note:  <code>show_children</code>
 * must be set to <code>true</code>.
 * <p>
 * If the option <code>get_sizes</code> is set to <code>true</code>, then the
 * sizes (objects and elements) of each table are returned (in
 * <code>sizes</code> and <code>full_sizes</code>), along with the total number
 * of objects in the requested table (in <code>total_size</code> and
 * <code>total_full_size</code>).
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_table_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_table_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/table", actual_request, callback);
};

/**
 * Retrieves detailed information about tables, views, and collections.
 * <p>
 * If <code>table_name</code> specifies a table or view, information specific
 * to that entity will be returned.
 * <p>
 * If <code>table_name</code> specifies a collection, the call can return
 * information about either the collection itself (setting the
 * <code>show_children</code> option to <code>false</code>) or the tables and
 * views it contains (setting <code>show_children</code> to <code>true</code>).
 * <p>
 * If <code>table_name</code> is empty, information about all collections and
 * top-level tables and views can be returned.  Note:
 * <code>show_children</code> must be set to <code>true</code>.
 * <p>
 * If <code>table_name</code> is '*', information about all tables,
 * collections, and views will be returned.  Note:  <code>show_children</code>
 * must be set to <code>true</code>.
 * <p>
 * If the option <code>get_sizes</code> is set to <code>true</code>, then the
 * sizes (objects and elements) of each table are returned (in
 * <code>sizes</code> and <code>full_sizes</code>), along with the total number
 * of objects in the requested table (in <code>total_size</code> and
 * <code>total_full_size</code>).
 *
 * @param {String} table_name  Name of the table for which to retrieve the
 *                             information. If blank, then information about
 *                             all collections and top-level tables and views
 *                             is returned.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'force_synchronous': If
 *                          <code>true</code> then the table sizes will wait
 *                          for read lock before returning.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'get_sizes': If <code>true</code> then
 *                          the table sizes will be returned; blank, otherwise.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'show_children': If
 *                          <code>table_name</code> is a collection, then
 *                          <code>true</code> will return information about the
 *                          children of the collection, while
 *                          <code>false</code> will return information about
 *                          the collection itself.
 *                          If <code>table_name</code> is empty or '*', then
 *                          <code>show_children</code> must be
 *                          <code>true</code> (or not specified); otherwise, no
 *                          results will be returned.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'true'.
 *                                  <li> 'no_error_if_not_exists': If
 *                          <code>false</code> will return an error if the
 *                          provided <code>table_name</code> does not exist. If
 *                          <code>true</code> then it will return an empty
 *                          result.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'get_column_info': If
 *                          <code>true</code> then column info (memory usage,
 *                          etc) will be returned.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_table = function(table_name, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_table(table_name, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/table", actual_request, callback);
};

/**
 * Retrieves the user provided metadata for the specified tables.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_table_metadata_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_table_metadata_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/table/metadata", actual_request, callback);
};

/**
 * Retrieves the user provided metadata for the specified tables.
 *
 * @param {String[]} table_names  Tables whose metadata will be fetched. All
 *                                provided tables must exist, or an error is
 *                                returned.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_table_metadata = function(table_names, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_table_metadata(table_names, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/table/metadata", actual_request, callback);
};

/**
 * Gets names of the tables whose type matches the given criteria. Each table
 * has a particular type. This type comprises the schema and properties of the
 * table and sometimes a type label. This function allows a look up of the
 * existing tables based on full or partial type information. The operation is
 * synchronous.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_tables_by_type_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_tables_by_type_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: request.type_id,
        label: request.label,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/tables/bytype", actual_request, callback);
};

/**
 * Gets names of the tables whose type matches the given criteria. Each table
 * has a particular type. This type comprises the schema and properties of the
 * table and sometimes a type label. This function allows a look up of the
 * existing tables based on full or partial type information. The operation is
 * synchronous.
 *
 * @param {String} type_id  Type id returned by a call to
 *                          {@linkcode GPUdb#create_type}.
 * @param {String} label  Optional user supplied label which can be used
 *                        instead of the type_id to retrieve all tables with
 *                        the given label.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_tables_by_type = function(type_id, label, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_tables_by_type(type_id, label, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: type_id,
        label: label,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/tables/bytype", actual_request, callback);
};

/**
 * Retrieves information regarding the specified triggers or all existing
 * triggers currently active.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_triggers_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_triggers_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        trigger_ids: request.trigger_ids,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/triggers", actual_request, callback);
};

/**
 * Retrieves information regarding the specified triggers or all existing
 * triggers currently active.
 *
 * @param {String[]} trigger_ids  List of IDs of the triggers whose information
 *                                is to be retrieved. An empty list means
 *                                information will be retrieved on all active
 *                                triggers.
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_triggers = function(trigger_ids, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_triggers(trigger_ids, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        trigger_ids: trigger_ids,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/triggers", actual_request, callback);
};

/**
 * Retrieves information for the specified data type ID or type label. For all
 * data types that match the input criteria, the database returns the type ID,
 * the type schema, the label (if available), and the type's column properties.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_types_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_types_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: request.type_id,
        label: request.label,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/show/types", actual_request, callback);
};

/**
 * Retrieves information for the specified data type ID or type label. For all
 * data types that match the input criteria, the database returns the type ID,
 * the type schema, the label (if available), and the type's column properties.
 *
 * @param {String} type_id  Type Id returned in response to a call to
 *                          {@linkcode GPUdb#create_type}.
 * @param {String} label  Option string that was supplied by user in a call to
 *                        {@linkcode GPUdb#create_type}.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'no_join_types': When set to 'true',
 *                          no join types will be included.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.show_types = function(type_id, label, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.show_types(type_id, label, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        type_id: type_id,
        label: label,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/show/types", actual_request, callback);
};

/**
 * Runs multiple predicate-based updates in a single call.  With the list of
 * given expressions, any matching record's column values will be updated as
 * provided in <code>new_values_maps</code>.  There is also an optional
 * 'upsert' capability where if a particular predicate doesn't match any
 * existing record, then a new record can be inserted.
 * <p>
 * Note that this operation can only be run on an original table and not on a
 * collection or a result view.
 * <p>
 * This operation can update primary key values.  By default only 'pure primary
 * key' predicates are allowed when updating primary key values. If the primary
 * key for a table is the column 'attr1', then the operation will only accept
 * predicates of the form: "attr1 == 'foo'" if the attr1 column is being
 * updated.  For a composite primary key (e.g. columns 'attr1' and 'attr2')
 * then this operation will only accept predicates of the form: "(attr1 ==
 * 'foo') and (attr2 == 'bar')".  Meaning, all primary key columns must appear
 * in an equality predicate in the expressions.  Furthermore each 'pure primary
 * key' predicate must be unique within a given request.  These restrictions
 * can be removed by utilizing some available options through
 * <code>options</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.update_records_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.update_records_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        expressions: request.expressions,
        new_values_maps: request.new_values_maps,
        records_to_insert: (request.records_to_insert !== undefined && request.records_to_insert !== null) ? request.records_to_insert : [],
        records_to_insert_str: (request.data !== undefined && request.data !== null) ? GPUdb.encode(request.data) : [],
        record_encoding: (request.record_encoding !== undefined && request.record_encoding !== null) ? request.record_encoding : "json",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/update/records", actual_request, callback);
};

/**
 * Runs multiple predicate-based updates in a single call.  With the list of
 * given expressions, any matching record's column values will be updated as
 * provided in <code>new_values_maps</code>.  There is also an optional
 * 'upsert' capability where if a particular predicate doesn't match any
 * existing record, then a new record can be inserted.
 * <p>
 * Note that this operation can only be run on an original table and not on a
 * collection or a result view.
 * <p>
 * This operation can update primary key values.  By default only 'pure primary
 * key' predicates are allowed when updating primary key values. If the primary
 * key for a table is the column 'attr1', then the operation will only accept
 * predicates of the form: "attr1 == 'foo'" if the attr1 column is being
 * updated.  For a composite primary key (e.g. columns 'attr1' and 'attr2')
 * then this operation will only accept predicates of the form: "(attr1 ==
 * 'foo') and (attr2 == 'bar')".  Meaning, all primary key columns must appear
 * in an equality predicate in the expressions.  Furthermore each 'pure primary
 * key' predicate must be unique within a given request.  These restrictions
 * can be removed by utilizing some available options through
 * <code>options</code>.
 *
 * @param {String} table_name  Table to be updated. Must be a currently
 *                             existing table and not a collection or view.
 * @param {String[]} expressions  A list of the actual predicates, one for each
 *                                update; format should follow the guidelines
 *                                [here]{@linkcode GPUdb#filter}.
 * @param {Object[]} new_values_maps  List of new values for the matching
 *                                    records.  Each element is a map with
 *                                    (key, value) pairs where the keys are the
 *                                    names of the columns whose values are to
 *                                    be updated; the values are the new
 *                                    values.  The number of elements in the
 *                                    list should match the length of
 *                                    <code>expressions</code>.
 * @param {Object[]} data  An optional list of new json-avro encoded objects to
 *                         insert, one for each update, to be added to the set
 *                         if the particular update did not affect any objects.
 * @param {Object} options  Optional parameters.
 *                          <ul>
 *                                  <li> 'global_expression': An optional
 *                          global expression to reduce the search space of the
 *                          predicates listed in <code>expressions</code>.  The
 *                          default value is ''.
 *                                  <li> 'bypass_safety_checks': When set to
 *                          <code>true</code>, all predicates are available for
 *                          primary key updates.  Keep in mind that it is
 *                          possible to destroy data in this case, since a
 *                          single predicate may match multiple objects
 *                          (potentially all of records of a table), and then
 *                          updating all of those records to have the same
 *                          primary key will, due to the primary key uniqueness
 *                          constraints, effectively delete all but one of
 *                          those updated records.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'update_on_existing_pk': Can be used
 *                          to customize behavior when the updated primary key
 *                          value already exists as described in
 *                          {@linkcode GPUdb#insert_records}.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'use_expressions_in_new_values_maps':
 *                          When set to <code>true</code>, all new values in
 *                          <code>new_values_maps</code> are considered as
 *                          expression values. When set to <code>false</code>,
 *                          all new values in <code>new_values_maps</code> are
 *                          considered as constants.  NOTE:  When
 *                          <code>true</code>, string constants will need to be
 *                          quoted to avoid being evaluated as expressions.
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'true'
 *                                  <li> 'false'
 *                          </ul>
 *                          The default value is 'false'.
 *                                  <li> 'record_id': ID of a single record to
 *                          be updated (returned in the call to
 *                          {@linkcode GPUdb#insert_records} or
 *                          {@linkcode GPUdb#get_records_from_collection}).
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.update_records = function(table_name, expressions, new_values_maps, data, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.update_records(table_name, expressions, new_values_maps, data, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        expressions: expressions,
        new_values_maps: new_values_maps,
        records_to_insert: [],
        records_to_insert_str: GPUdb.encode(data),
        record_encoding: "json",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/update/records", actual_request, callback);
};

/**
 * Updates the view specified by <code>table_name</code> to include full series
 * (track) information from the <code>world_table_name</code> for the series
 * (tracks) present in the <code>view_name</code>.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.update_records_by_series_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.update_records_by_series_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        world_table_name: request.world_table_name,
        view_name: (request.view_name !== undefined && request.view_name !== null) ? request.view_name : "",
        reserved: (request.reserved !== undefined && request.reserved !== null) ? request.reserved : [],
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/update/records/byseries", actual_request, callback);
};

/**
 * Updates the view specified by <code>table_name</code> to include full series
 * (track) information from the <code>world_table_name</code> for the series
 * (tracks) present in the <code>view_name</code>.
 *
 * @param {String} table_name  Name of the view on which the update operation
 *                             will be performed. Must be an existing view.
 * @param {String} world_table_name  Name of the table containing the complete
 *                                   series (track) information.
 * @param {String} view_name  Optional name of the view containing the series
 *                            (tracks) which have to be updated.
 * @param {String[]} reserved
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.update_records_by_series = function(table_name, world_table_name, view_name, reserved, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.update_records_by_series(table_name, world_table_name, view_name, reserved, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        world_table_name: world_table_name,
        view_name: (view_name !== undefined && view_name !== null) ? view_name : "",
        reserved: (reserved !== undefined && reserved !== null) ? reserved : [],
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/update/records/byseries", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        world_table_names: request.world_table_names,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        geometry_column_name: request.geometry_column_name,
        track_ids: request.track_ids,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        bg_color: request.bg_color,
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String[]} world_table_names
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} geometry_column_name
 * @param {String[][]} track_ids
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Number} bg_color
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'do_points':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_shapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_tracks':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_symbology':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'false'.
 *                                        <li> 'pointcolors':
 *                                        <li> 'pointsizes': The default value
 *                                is '3'.
 *                                        <li> 'pointoffset_x': The default
 *                                value is '0'.
 *                                        <li> 'pointoffset_y': The default
 *                                value is '0'.
 *                                        <li> 'pointshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'square'.
 *                                        <li> 'symbolrotations': The default
 *                                value is '0'.
 *                                        <li> 'shapelinewidths': The default
 *                                value is '3'.
 *                                        <li> 'shapelinecolors': The default
 *                                value is 'FFFF00 '.
 *                                        <li> 'shapelinepatterns': The default
 *                                value is '0'.
 *                                        <li> 'shapelinepatternlen': The
 *                                default value is '32'.
 *                                        <li> 'shapefillcolors': The default
 *                                value is '-1'.
 *                                        <li> 'hashlineintervals': The default
 *                                value is '20'.
 *                                        <li> 'hashlinecolors': The default
 *                                value is 'The same as line color.'.
 *                                        <li> 'hashlineangles': The default
 *                                value is '0'.
 *                                        <li> 'hashlinelens': The default
 *                                value is '0'.
 *                                        <li> 'hashlinewidths': The default
 *                                value is '3'.
 *                                        <li> 'tracklinewidths': The default
 *                                value is '3'.
 *                                        <li> 'tracklinecolors': The default
 *                                value is '00FF00'.
 *                                        <li> 'trackmarkersizes': The default
 *                                value is '3'.
 *                                        <li> 'trackmarkercolors': The default
 *                                value is '0000FF'.
 *                                        <li> 'trackmarkershapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'oriented_arrow'
 *                                        <li> 'oriented_triangle'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'circle'.
 *                                        <li> 'trackheadcolors': The default
 *                                value is 'FFFFFF'.
 *                                        <li> 'trackheadsizes': The default
 *                                value is '10'.
 *                                        <li> 'trackheadshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'hollowdiamond'.
 *                                </ul>
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image = function(table_names, world_table_names, x_column_name, y_column_name, geometry_column_name, track_ids, min_x, max_x, min_y, max_y, width, height, projection, bg_color, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image(table_names, world_table_names, x_column_name, y_column_name, geometry_column_name, track_ids, min_x, max_x, min_y, max_y, width, height, projection, bg_color, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        world_table_names: world_table_names,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        geometry_column_name: geometry_column_name,
        track_ids: track_ids,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        bg_color: bg_color,
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image", actual_request, callback);
};

/**
 * Scatter plot is the only plot type currently supported. A non-numeric column
 * can be specified as x or y column and jitters can be added to them to avoid
 * excessive overlapping. All color values must be in the format RRGGBB or
 * AARRGGBB (to specify the alpha value).
 * The image is contained in the <code>image_data</code> field.
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.visualize_image_chart_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_chart_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        x_column_names: request.x_column_names,
        y_column_names: request.y_column_names,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        bg_color: request.bg_color,
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image/chart", actual_request, callback);
};

/**
 * Scatter plot is the only plot type currently supported. A non-numeric column
 * can be specified as x or y column and jitters can be added to them to avoid
 * excessive overlapping. All color values must be in the format RRGGBB or
 * AARRGGBB (to specify the alpha value).
 * The image is contained in the <code>image_data</code> field.
 *
 * @param {String} table_name  Name of the table containing the data to be
 *                             drawn as a chart.
 * @param {String[]} x_column_names  Names of the columns containing the data
 *                                   mapped to the x axis of a chart.
 * @param {String[]} y_column_names  Names of the columns containing the data
 *                                   mapped to the y axis of a chart.
 * @param {Number} min_x  Lower bound for the x column values. For non-numeric
 *                        x column, each x column item is mapped to an integral
 *                        value starting from 0.
 * @param {Number} max_x  Upper bound for the x column values. For non-numeric
 *                        x column, each x column item is mapped to an integral
 *                        value starting from 0.
 * @param {Number} min_y  Lower bound for the y column values. For non-numeric
 *                        y column, each y column item is mapped to an integral
 *                        value starting from 0.
 * @param {Number} max_y  Upper bound for the y column values. For non-numeric
 *                        y column, each y column item is mapped to an integral
 *                        value starting from 0.
 * @param {Number} width  Width of the generated image in pixels.
 * @param {Number} height  Height of the generated image in pixels.
 * @param {String} bg_color  Background color of the generated image.
 * @param {Object} style_options  Rendering style options for a chart.
 *                                <ul>
 *                                        <li> 'pointcolor': The color of
 *                                points in the plot represented as a
 *                                hexadecimal number.  The default value is
 *                                '0000FF'.
 *                                        <li> 'pointsize': The size of points
 *                                in the plot represented as number of pixels.
 *                                The default value is '3'.
 *                                        <li> 'pointshape': The shape of
 *                                points in the plot.
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                </ul>
 *                                The default value is 'square'.
 *                                        <li> 'cb_pointcolors': Point color
 *                                class break information consisting of three
 *                                entries: class-break attribute, class-break
 *                                values/ranges, and point color values. This
 *                                option overrides the pointcolor option if
 *                                both are provided. Class-break ranges are
 *                                represented in the form of "min:max".
 *                                Class-break values/ranges and point color
 *                                values are separated by cb_delimiter, e.g.
 *                                {"price", "20:30;30:40;40:50",
 *                                "0xFF0000;0x00FF00;0x0000FF"}.
 *                                        <li> 'cb_pointsizes': Point size
 *                                class break information consisting of three
 *                                entries: class-break attribute, class-break
 *                                values/ranges, and point size values. This
 *                                option overrides the pointsize option if both
 *                                are provided. Class-break ranges are
 *                                represented in the form of "min:max".
 *                                Class-break values/ranges and point size
 *                                values are separated by cb_delimiter, e.g.
 *                                {"states", "NY;TX;CA", "3;5;7"}.
 *                                        <li> 'cb_pointshapes': Point shape
 *                                class break information consisting of three
 *                                entries: class-break attribute, class-break
 *                                values/ranges, and point shape names. This
 *                                option overrides the pointshape option if
 *                                both are provided. Class-break ranges are
 *                                represented in the form of "min:max".
 *                                Class-break values/ranges and point shape
 *                                names are separated by cb_delimiter, e.g.
 *                                {"states", "NY;TX;CA",
 *                                "circle;square;diamond"}.
 *                                        <li> 'cb_delimiter': A character or
 *                                string which separates per-class values in a
 *                                class-break style option string.  The default
 *                                value is ';'.
 *                                        <li> 'x_order_by': An expression or
 *                                aggregate expression by which non-numeric x
 *                                column values are sorted, e.g. "avg(price)
 *                                descending".
 *                                        <li> 'y_order_by': An expression or
 *                                aggregate expression by which non-numeric y
 *                                column values are sorted, e.g. "avg(price)",
 *                                which defaults to "avg(price) ascending".
 *                                        <li> 'scale_type_x': Type of x axis
 *                                scale.
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none': No scale is applied to
 *                                the x axis.
 *                                        <li> 'log': A base-10 log scale is
 *                                applied to the x axis.
 *                                </ul>
 *                                The default value is 'none'.
 *                                        <li> 'scale_type_y': Type of y axis
 *                                scale.
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none': No scale is applied to
 *                                the y axis.
 *                                        <li> 'log': A base-10 log scale is
 *                                applied to the y axis.
 *                                </ul>
 *                                The default value is 'none'.
 *                                        <li> 'min_max_scaled': If this
 *                                options is set to "false", this endpoint
 *                                expects request's min/max values are not yet
 *                                scaled. They will be scaled according to
 *                                scale_type_x or scale_type_y for response. If
 *                                this options is set to "true", this endpoint
 *                                expects request's min/max values are already
 *                                scaled according to
 *                                scale_type_x/scale_type_y. Response's min/max
 *                                values will be equal to request's min/max
 *                                values.  The default value is 'false'.
 *                                        <li> 'jitter_x': Amplitude of
 *                                horizontal jitter applied to non-numeric x
 *                                column values.  The default value is '0.0'.
 *                                        <li> 'jitter_y': Amplitude of
 *                                vertical jitter applied to non-numeric y
 *                                column values.  The default value is '0.0'.
 *                                        <li> 'plot_all': If this options is
 *                                set to "true", all non-numeric column values
 *                                are plotted ignoring min_x, max_x, min_y and
 *                                max_y parameters.  The default value is
 *                                'false'.
 *                                </ul>
 * @param {Object} options  Optional parameters.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 */
GPUdb.prototype.visualize_image_chart = function(table_name, x_column_names, y_column_names, min_x, max_x, min_y, max_y, width, height, bg_color, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_chart(table_name, x_column_names, y_column_names, min_x, max_x, min_y, max_y, width, height, bg_color, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        x_column_names: x_column_names,
        y_column_names: y_column_names,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        bg_color: bg_color,
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image/chart", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_classbreak_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_classbreak_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        world_table_names: request.world_table_names,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        geometry_column_name: request.geometry_column_name,
        track_ids: request.track_ids,
        cb_attr: request.cb_attr,
        cb_vals: request.cb_vals,
        cb_pointcolor_attr: request.cb_pointcolor_attr,
        cb_pointcolor_vals: request.cb_pointcolor_vals,
        cb_pointsize_attr: request.cb_pointsize_attr,
        cb_pointsize_vals: request.cb_pointsize_vals,
        cb_pointshape_attr: request.cb_pointshape_attr,
        cb_pointshape_vals: request.cb_pointshape_vals,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        bg_color: request.bg_color,
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image/classbreak", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String[]} world_table_names
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} geometry_column_name
 * @param {String[][]} track_ids
 * @param {String} cb_attr
 * @param {String[]} cb_vals
 * @param {String} cb_pointcolor_attr
 * @param {String[]} cb_pointcolor_vals
 * @param {String} cb_pointsize_attr
 * @param {String[]} cb_pointsize_vals
 * @param {String} cb_pointshape_attr
 * @param {String[]} cb_pointshape_vals
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Number} bg_color
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'do_points':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_shapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_tracks':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_symbology':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'false'.
 *                                        <li> 'pointcolors': The default value
 *                                is 'FF0000'.
 *                                        <li> 'pointsizes': The default value
 *                                is '3'.
 *                                        <li> 'pointoffset_x': The default
 *                                value is '0'.
 *                                        <li> 'pointoffset_y': The default
 *                                value is '0'.
 *                                        <li> 'pointshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'none'.
 *                                        <li> 'shapelinewidths': The default
 *                                value is '3'.
 *                                        <li> 'shapelinecolors': The default
 *                                value is 'FFFF00 '.
 *                                        <li> 'shapelinepatterns': The default
 *                                value is '0'.
 *                                        <li> 'shapelinepatternlen': The
 *                                default value is '32'.
 *                                        <li> 'shapefillcolors': The default
 *                                value is '-1'.
 *                                        <li> 'hashlineintervals': The default
 *                                value is '20'.
 *                                        <li> 'hashlinecolors': The default
 *                                value is 'The same as line color.'.
 *                                        <li> 'hashlineangles': The default
 *                                value is '0'.
 *                                        <li> 'hashlinelens': The default
 *                                value is '0'.
 *                                        <li> 'hashlinewidths': The default
 *                                value is '3'.
 *                                        <li> 'tracklinewidths': The default
 *                                value is '3'.
 *                                        <li> 'tracklinecolors': The default
 *                                value is '00FF00'.
 *                                        <li> 'trackmarkersizes': The default
 *                                value is '3'.
 *                                        <li> 'trackmarkercolors': The default
 *                                value is '0000FF'.
 *                                        <li> 'trackmarkershapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'none'.
 *                                        <li> 'trackheadcolors': The default
 *                                value is 'FFFFFF'.
 *                                        <li> 'trackheadsizes': The default
 *                                value is '10'.
 *                                        <li> 'trackheadshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'circle'.
 *                                </ul>
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_classbreak = function(table_names, world_table_names, x_column_name, y_column_name, geometry_column_name, track_ids, cb_attr, cb_vals, cb_pointcolor_attr, cb_pointcolor_vals, cb_pointsize_attr, cb_pointsize_vals, cb_pointshape_attr, cb_pointshape_vals, min_x, max_x, min_y, max_y, width, height, projection, bg_color, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_classbreak(table_names, world_table_names, x_column_name, y_column_name, geometry_column_name, track_ids, cb_attr, cb_vals, cb_pointcolor_attr, cb_pointcolor_vals, cb_pointsize_attr, cb_pointsize_vals, cb_pointshape_attr, cb_pointshape_vals, min_x, max_x, min_y, max_y, width, height, projection, bg_color, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        world_table_names: world_table_names,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        geometry_column_name: geometry_column_name,
        track_ids: track_ids,
        cb_attr: cb_attr,
        cb_vals: cb_vals,
        cb_pointcolor_attr: cb_pointcolor_attr,
        cb_pointcolor_vals: cb_pointcolor_vals,
        cb_pointsize_attr: cb_pointsize_attr,
        cb_pointsize_vals: cb_pointsize_vals,
        cb_pointshape_attr: cb_pointshape_attr,
        cb_pointshape_vals: cb_pointshape_vals,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        bg_color: bg_color,
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image/classbreak", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_contour_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_contour_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        value_column_name: request.value_column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image/contour", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} value_column_name
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> '3857'
 *                                     <li> '102100'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> 'EPSG:900913'
 *                                     <li> 'EPSG:102100'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'line_size': The default value
 *                                is '3'.
 *                                        <li> 'color': The default value is
 *                                'FF696969'.
 *                                        <li> 'bg_color': The default value is
 *                                '00000000'.
 *                                        <li> 'text_color': The default value
 *                                is 'FF000000'.
 *                                        <li> 'colormap':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'jet'
 *                                        <li> 'accent'
 *                                        <li> 'afmhot'
 *                                        <li> 'autumn'
 *                                        <li> 'binary'
 *                                        <li> 'blues'
 *                                        <li> 'bone'
 *                                        <li> 'brbg'
 *                                        <li> 'brg'
 *                                        <li> 'bugn'
 *                                        <li> 'bupu'
 *                                        <li> 'bwr'
 *                                        <li> 'cmrmap'
 *                                        <li> 'cool'
 *                                        <li> 'coolwarm'
 *                                        <li> 'copper'
 *                                        <li> 'cubehelix'
 *                                        <li> 'dark2'
 *                                        <li> 'flag'
 *                                        <li> 'gist_earth'
 *                                        <li> 'gist_gray'
 *                                        <li> 'gist_heat'
 *                                        <li> 'gist_ncar'
 *                                        <li> 'gist_rainbow'
 *                                        <li> 'gist_stern'
 *                                        <li> 'gist_yarg'
 *                                        <li> 'gnbu'
 *                                        <li> 'gnuplot2'
 *                                        <li> 'gnuplot'
 *                                        <li> 'gray'
 *                                        <li> 'greens'
 *                                        <li> 'greys'
 *                                        <li> 'hot'
 *                                        <li> 'hsv'
 *                                        <li> 'inferno'
 *                                        <li> 'magma'
 *                                        <li> 'nipy_spectral'
 *                                        <li> 'ocean'
 *                                        <li> 'oranges'
 *                                        <li> 'orrd'
 *                                        <li> 'paired'
 *                                        <li> 'pastel1'
 *                                        <li> 'pastel2'
 *                                        <li> 'pink'
 *                                        <li> 'piyg'
 *                                        <li> 'plasma'
 *                                        <li> 'prgn'
 *                                        <li> 'prism'
 *                                        <li> 'pubu'
 *                                        <li> 'pubugn'
 *                                        <li> 'puor'
 *                                        <li> 'purd'
 *                                        <li> 'purples'
 *                                        <li> 'rainbow'
 *                                        <li> 'rdbu'
 *                                        <li> 'rdgy'
 *                                        <li> 'rdpu'
 *                                        <li> 'rdylbu'
 *                                        <li> 'rdylgn'
 *                                        <li> 'reds'
 *                                        <li> 'seismic'
 *                                        <li> 'set1'
 *                                        <li> 'set2'
 *                                        <li> 'set3'
 *                                        <li> 'spectral'
 *                                        <li> 'spring'
 *                                        <li> 'summer'
 *                                        <li> 'terrain'
 *                                        <li> 'viridis'
 *                                        <li> 'winter'
 *                                        <li> 'wistia'
 *                                        <li> 'ylgn'
 *                                        <li> 'ylgnbu'
 *                                        <li> 'ylorbr'
 *                                        <li> 'ylorrd'
 *                                </ul>
 *                                The default value is 'jet'.
 *                                </ul>
 * @param {Object} options
 *                          <ul>
 *                                  <li> 'min_level':
 *                                  <li> 'max_level':
 *                                  <li> 'num_levels': The default value is
 *                          '10'.
 *                                  <li> 'adjust_levels': The default value is
 *                          'true'.
 *                                  <li> 'search_radius': The default value is
 *                          '20'.
 *                                  <li> 'max_search_cells': The default value
 *                          is '100'.
 *                                  <li> 'gridding_method':
 *                          Supported values:
 *                          <ul>
 *                                  <li> 'INV_DST_POW'
 *                                  <li> 'MIN_CURV'
 *                                  <li> 'KRIGING'
 *                                  <li> 'PASS_THROUGH'
 *                                  <li> 'FILL_RATIO'
 *                          </ul>
 *                          The default value is 'INV_DST_POW'.
 *                                  <li> 'smoothing_factor': The default value
 *                          is '10'.
 *                                  <li> 'grid_size': The default value is
 *                          '100'.
 *                                  <li> 'adjust_grid': The default value is
 *                          'false'.
 *                                  <li> 'adjust_grid_neigh': The default value
 *                          is '1'.
 *                                  <li> 'adjust_grid_size': The default value
 *                          is '1'.
 *                                  <li> 'max_grid_size': The default value is
 *                          '500'.
 *                                  <li> 'min_grid_size': The default value is
 *                          '10'.
 *                                  <li> 'render_output_grid': The default
 *                          value is 'false'.
 *                                  <li> 'color_isolines': The default value is
 *                          'true'.
 *                                  <li> 'add_labels': The default value is
 *                          'false'.
 *                                  <li> 'labels_font_size': The default value
 *                          is '12'.
 *                                  <li> 'labels_font_family': The default
 *                          value is 'arial'.
 *                                  <li> 'labels_search_window': The default
 *                          value is '4'.
 *                                  <li> 'labels_intralevel_separation': The
 *                          default value is '4'.
 *                                  <li> 'labels_interlevel_separation': The
 *                          default value is '20'.
 *                                  <li> 'labels_max_angle': The default value
 *                          is '60'.
 *                          </ul>
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_contour = function(table_names, x_column_name, y_column_name, value_column_name, min_x, max_x, min_y, max_y, width, height, projection, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_contour(table_names, x_column_name, y_column_name, value_column_name, min_x, max_x, min_y, max_y, width, height, projection, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        value_column_name: value_column_name,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image/contour", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_heatmap_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_heatmap_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        value_column_name: request.value_column_name,
        geometry_column_name: request.geometry_column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image/heatmap", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} value_column_name
 * @param {String} geometry_column_name
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'colormap':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'jet'
 *                                        <li> 'accent'
 *                                        <li> 'afmhot'
 *                                        <li> 'autumn'
 *                                        <li> 'binary'
 *                                        <li> 'blues'
 *                                        <li> 'bone'
 *                                        <li> 'brbg'
 *                                        <li> 'brg'
 *                                        <li> 'bugn'
 *                                        <li> 'bupu'
 *                                        <li> 'bwr'
 *                                        <li> 'cmrmap'
 *                                        <li> 'cool'
 *                                        <li> 'coolwarm'
 *                                        <li> 'copper'
 *                                        <li> 'cubehelix'
 *                                        <li> 'dark2'
 *                                        <li> 'flag'
 *                                        <li> 'gist_earth'
 *                                        <li> 'gist_gray'
 *                                        <li> 'gist_heat'
 *                                        <li> 'gist_ncar'
 *                                        <li> 'gist_rainbow'
 *                                        <li> 'gist_stern'
 *                                        <li> 'gist_yarg'
 *                                        <li> 'gnbu'
 *                                        <li> 'gnuplot2'
 *                                        <li> 'gnuplot'
 *                                        <li> 'gray'
 *                                        <li> 'greens'
 *                                        <li> 'greys'
 *                                        <li> 'hot'
 *                                        <li> 'hsv'
 *                                        <li> 'inferno'
 *                                        <li> 'magma'
 *                                        <li> 'nipy_spectral'
 *                                        <li> 'ocean'
 *                                        <li> 'oranges'
 *                                        <li> 'orrd'
 *                                        <li> 'paired'
 *                                        <li> 'pastel1'
 *                                        <li> 'pastel2'
 *                                        <li> 'pink'
 *                                        <li> 'piyg'
 *                                        <li> 'plasma'
 *                                        <li> 'prgn'
 *                                        <li> 'prism'
 *                                        <li> 'pubu'
 *                                        <li> 'pubugn'
 *                                        <li> 'puor'
 *                                        <li> 'purd'
 *                                        <li> 'purples'
 *                                        <li> 'rainbow'
 *                                        <li> 'rdbu'
 *                                        <li> 'rdgy'
 *                                        <li> 'rdpu'
 *                                        <li> 'rdylbu'
 *                                        <li> 'rdylgn'
 *                                        <li> 'reds'
 *                                        <li> 'seismic'
 *                                        <li> 'set1'
 *                                        <li> 'set2'
 *                                        <li> 'set3'
 *                                        <li> 'spectral'
 *                                        <li> 'spring'
 *                                        <li> 'summer'
 *                                        <li> 'terrain'
 *                                        <li> 'viridis'
 *                                        <li> 'winter'
 *                                        <li> 'wistia'
 *                                        <li> 'ylgn'
 *                                        <li> 'ylgnbu'
 *                                        <li> 'ylorbr'
 *                                        <li> 'ylorrd'
 *                                </ul>
 *                                The default value is 'jet'.
 *                                        <li> 'blur_radius': The default value
 *                                is '5'.
 *                                        <li> 'bg_color':
 *                                        <li> 'gradient_start_color': The
 *                                default value is 'FFFFFF'.
 *                                        <li> 'gradient_end_color': The
 *                                default value is 'FF0000'.
 *                                </ul>
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_heatmap = function(table_names, x_column_name, y_column_name, value_column_name, geometry_column_name, min_x, max_x, min_y, max_y, width, height, projection, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_heatmap(table_names, x_column_name, y_column_name, value_column_name, geometry_column_name, min_x, max_x, min_y, max_y, width, height, projection, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        value_column_name: value_column_name,
        geometry_column_name: geometry_column_name,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image/heatmap", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_labels_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_labels_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: request.table_name,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        x_offset: (request.x_offset !== undefined && request.x_offset !== null) ? request.x_offset : "",
        y_offset: (request.y_offset !== undefined && request.y_offset !== null) ? request.y_offset : "",
        text_string: request.text_string,
        font: (request.font !== undefined && request.font !== null) ? request.font : "",
        text_color: (request.text_color !== undefined && request.text_color !== null) ? request.text_color : "",
        text_angle: (request.text_angle !== undefined && request.text_angle !== null) ? request.text_angle : "",
        text_scale: (request.text_scale !== undefined && request.text_scale !== null) ? request.text_scale : "",
        draw_box: (request.draw_box !== undefined && request.draw_box !== null) ? request.draw_box : "",
        draw_leader: (request.draw_leader !== undefined && request.draw_leader !== null) ? request.draw_leader : "",
        line_width: (request.line_width !== undefined && request.line_width !== null) ? request.line_width : "",
        line_color: (request.line_color !== undefined && request.line_color !== null) ? request.line_color : "",
        fill_color: (request.fill_color !== undefined && request.fill_color !== null) ? request.fill_color : "",
        leader_x_column_name: (request.leader_x_column_name !== undefined && request.leader_x_column_name !== null) ? request.leader_x_column_name : "",
        leader_y_column_name: (request.leader_y_column_name !== undefined && request.leader_y_column_name !== null) ? request.leader_y_column_name : "",
        filter: (request.filter !== undefined && request.filter !== null) ? request.filter : "",
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/image/labels", actual_request, callback);
};

/**
 *
 * @param {String} table_name
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} x_offset
 * @param {String} y_offset
 * @param {String} text_string
 * @param {String} font
 * @param {String} text_color
 * @param {String} text_angle
 * @param {String} text_scale
 * @param {String} draw_box
 * @param {String} draw_leader
 * @param {String} line_width
 * @param {String} line_color
 * @param {String} fill_color
 * @param {String} leader_x_column_name
 * @param {String} leader_y_column_name
 * @param {String} filter
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_image_labels = function(table_name, x_column_name, y_column_name, x_offset, y_offset, text_string, font, text_color, text_angle, text_scale, draw_box, draw_leader, line_width, line_color, fill_color, leader_x_column_name, leader_y_column_name, filter, min_x, max_x, min_y, max_y, width, height, projection, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_image_labels(table_name, x_column_name, y_column_name, x_offset, y_offset, text_string, font, text_color, text_angle, text_scale, draw_box, draw_leader, line_width, line_color, fill_color, leader_x_column_name, leader_y_column_name, filter, min_x, max_x, min_y, max_y, width, height, projection, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_name: table_name,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        x_offset: (x_offset !== undefined && x_offset !== null) ? x_offset : "",
        y_offset: (y_offset !== undefined && y_offset !== null) ? y_offset : "",
        text_string: text_string,
        font: (font !== undefined && font !== null) ? font : "",
        text_color: (text_color !== undefined && text_color !== null) ? text_color : "",
        text_angle: (text_angle !== undefined && text_angle !== null) ? text_angle : "",
        text_scale: (text_scale !== undefined && text_scale !== null) ? text_scale : "",
        draw_box: (draw_box !== undefined && draw_box !== null) ? draw_box : "",
        draw_leader: (draw_leader !== undefined && draw_leader !== null) ? draw_leader : "",
        line_width: (line_width !== undefined && line_width !== null) ? line_width : "",
        line_color: (line_color !== undefined && line_color !== null) ? line_color : "",
        fill_color: (fill_color !== undefined && fill_color !== null) ? fill_color : "",
        leader_x_column_name: (leader_x_column_name !== undefined && leader_x_column_name !== null) ? leader_x_column_name : "",
        leader_y_column_name: (leader_y_column_name !== undefined && leader_y_column_name !== null) ? leader_y_column_name : "",
        filter: (filter !== undefined && filter !== null) ? filter : "",
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/image/labels", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_video_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_video_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        world_table_names: request.world_table_names,
        track_ids: request.track_ids,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        geometry_column_name: request.geometry_column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        bg_color: request.bg_color,
        time_intervals: request.time_intervals,
        video_style: request.video_style,
        session_key: request.session_key,
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/video", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String[]} world_table_names
 * @param {String[][]} track_ids
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {String} geometry_column_name
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {Number} bg_color
 * @param {Number[][]} time_intervals
 * @param {String} video_style
 * @param {String} session_key
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'do_points':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_shapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'do_tracks':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'true'
 *                                        <li> 'false'
 *                                </ul>
 *                                The default value is 'true'.
 *                                        <li> 'pointcolors': The default value
 *                                is 'FF0000'.
 *                                        <li> 'pointsizes': The default value
 *                                is '3'.
 *                                        <li> 'pointshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                        <li> 'shapelinewidths': The default
 *                                value is '3'.
 *                                        <li> 'shapelinecolors': The default
 *                                value is 'FFFF00 '.
 *                                        <li> 'shapefillcolors': The default
 *                                value is '-1'.
 *                                        <li> 'tracklinewidths': The default
 *                                value is '3'.
 *                                        <li> 'tracklinecolors': The default
 *                                value is '00FF00'.
 *                                        <li> 'trackmarkersizes': The default
 *                                value is '3'.
 *                                        <li> 'trackmarkercolors': The default
 *                                value is '0000FF'.
 *                                        <li> 'trackmarkershapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'none'.
 *                                        <li> 'trackheadcolors': The default
 *                                value is 'FFFFFF'.
 *                                        <li> 'trackheadsizes': The default
 *                                value is '10'.
 *                                        <li> 'trackheadshapes':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'none'
 *                                        <li> 'circle'
 *                                        <li> 'square'
 *                                        <li> 'diamond'
 *                                        <li> 'hollowcircle'
 *                                        <li> 'hollowsquare'
 *                                        <li> 'hollowdiamond'
 *                                        <li> 'SYMBOLCODE'
 *                                </ul>
 *                                The default value is 'circle'.
 *                                </ul>
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_video = function(table_names, world_table_names, track_ids, x_column_name, y_column_name, geometry_column_name, min_x, max_x, min_y, max_y, width, height, projection, bg_color, time_intervals, video_style, session_key, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_video(table_names, world_table_names, track_ids, x_column_name, y_column_name, geometry_column_name, min_x, max_x, min_y, max_y, width, height, projection, bg_color, time_intervals, video_style, session_key, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        world_table_names: world_table_names,
        track_ids: track_ids,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        geometry_column_name: geometry_column_name,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        bg_color: bg_color,
        time_intervals: time_intervals,
        video_style: video_style,
        session_key: session_key,
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/video", actual_request, callback);
};

/**
 *
 * @param {Object} request  Request object containing the parameters for the
 *                          operation.
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_video_heatmap_request = function(request, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_video_heatmap_request(request, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: request.table_names,
        x_column_name: request.x_column_name,
        y_column_name: request.y_column_name,
        min_x: request.min_x,
        max_x: request.max_x,
        min_y: request.min_y,
        max_y: request.max_y,
        time_intervals: request.time_intervals,
        width: request.width,
        height: request.height,
        projection: (request.projection !== undefined && request.projection !== null) ? request.projection : "PLATE_CARREE",
        video_style: request.video_style,
        session_key: request.session_key,
        style_options: request.style_options,
        options: (request.options !== undefined && request.options !== null) ? request.options : {}
    };

    this.submit_request("/visualize/video/heatmap", actual_request, callback);
};

/**
 *
 * @param {String[]} table_names
 * @param {String} x_column_name
 * @param {String} y_column_name
 * @param {Number} min_x
 * @param {Number} max_x
 * @param {Number} min_y
 * @param {Number} max_y
 * @param {Number[][]} time_intervals
 * @param {Number} width
 * @param {Number} height
 * @param {String} projection
 *                             Supported values:
 *                             <ul>
 *                                     <li> 'EPSG:4326'
 *                                     <li> 'PLATE_CARREE'
 *                                     <li> '900913'
 *                                     <li> 'EPSG:900913'
 *                                     <li> '102100'
 *                                     <li> 'EPSG:102100'
 *                                     <li> '3857'
 *                                     <li> 'EPSG:3857'
 *                                     <li> 'WEB_MERCATOR'
 *                             </ul>
 *                             The default value is 'PLATE_CARREE'.
 * @param {String} video_style
 * @param {String} session_key
 * @param {Object} style_options
 *                                <ul>
 *                                        <li> 'colormap':
 *                                Supported values:
 *                                <ul>
 *                                        <li> 'jet'
 *                                        <li> 'hot'
 *                                        <li> 'hsv'
 *                                        <li> 'gray'
 *                                        <li> 'blues'
 *                                        <li> 'greens'
 *                                        <li> 'greys'
 *                                        <li> 'oranges'
 *                                        <li> 'purples'
 *                                        <li> 'reds'
 *                                </ul>
 *                                The default value is 'reds'.
 *                                        <li> 'blur_radius': The default value
 *                                is '5'.
 *                                        <li> 'bg_color': The default value is
 *                                'FF000000'.
 *                                        <li> 'gradient_start_color': The
 *                                default value is 'FFFFFF'.
 *                                        <li> 'gradient_end_color': The
 *                                default value is 'FF0000'.
 *                                </ul>
 * @param {Object} options
 * @param {GPUdbCallback} callback  Callback that handles the response.
 * 
 * @returns {Promise} A promise that will be fulfilled with the response
 *                    object, if no callback function is provided.
 * @private
 */
GPUdb.prototype.visualize_video_heatmap = function(table_names, x_column_name, y_column_name, min_x, max_x, min_y, max_y, time_intervals, width, height, projection, video_style, session_key, style_options, options, callback) {
    if (callback === undefined || callback === null) {
        var self = this;

        return new Promise( function( resolve, reject) {
            self.visualize_video_heatmap(table_names, x_column_name, y_column_name, min_x, max_x, min_y, max_y, time_intervals, width, height, projection, video_style, session_key, style_options, options, function(err, response) {
                if (err !== null) {
                    reject(err);
                } else {
                    resolve( response );
                }
            });
        });
    }

    var actual_request = {
        table_names: table_names,
        x_column_name: x_column_name,
        y_column_name: y_column_name,
        min_x: min_x,
        max_x: max_x,
        min_y: min_y,
        max_y: max_y,
        time_intervals: time_intervals,
        width: width,
        height: height,
        projection: (projection !== undefined && projection !== null) ? projection : "PLATE_CARREE",
        video_style: video_style,
        session_key: session_key,
        style_options: style_options,
        options: (options !== undefined && options !== null) ? options : {}
    };

    this.submit_request("/visualize/video/heatmap", actual_request, callback);
};