constructor(col) {
        super();

        if (typeof col === 'string') {
            const info = parseColumn(col);
            this.name = info.name;
            if ('mod' in info) {
                this.mod = info.mod;
            }
            if ('cnd' in info) {
                this.cnd = info.cnd;
            }
        } else {
            col = assert(col, ['name', 'prop', 'mod', 'cast', 'cnd', 'def', 'init', 'skip']);
            if ('name' in col) {
                if (!npm.utils.isText(col.name)) {
                    throw new TypeError(`Invalid 'name' value: ${npm.utils.toJson(col.name)}. A non-empty string was expected.`);
                }
                if (npm.utils.isNull(col.prop) && !isValidVariable(col.name)) {
                    throw new TypeError(`Invalid 'name' syntax: ${npm.utils.toJson(col.name)}.`);
                }
                this.name = col.name; // column name + property name (if 'prop' isn't specified)

                if (!npm.utils.isNull(col.prop)) {
                    if (!npm.utils.isText(col.prop)) {
                        throw new TypeError(`Invalid 'prop' value: ${npm.utils.toJson(col.prop)}. A non-empty string was expected.`);
                    }
                    if (!isValidVariable(col.prop)) {
                        throw new TypeError(`Invalid 'prop' syntax: ${npm.utils.toJson(col.prop)}.`);
                    }
                    if (col.prop !== col.name) {
                        // optional property name, if different from the column's name;
                        this.prop = col.prop;
                    }
                }
                if (!npm.utils.isNull(col.mod)) {
                    if (typeof col.mod !== 'string' || !isValidMod(col.mod)) {
                        throw new TypeError(`Invalid 'mod' value: ${npm.utils.toJson(col.mod)}.`);
                    }
                    this.mod = col.mod; // optional format modifier;
                }
                if (!npm.utils.isNull(col.cast)) {
                    this.cast = parseCast(col.cast); // optional SQL type casting
                }
                if ('cnd' in col) {
                    this.cnd = !!col.cnd;
                }
                if ('def' in col) {
                    this.def = col.def; // optional default
                }
                if (typeof col.init === 'function') {
                    this.init = col.init; // optional value override (overrides 'def' also)
                }
                if (typeof col.skip === 'function') {
                    this.skip = col.skip;
                }
            } else {
                throw new TypeError('Invalid column details.');
            }
        }

        const variable = '${' + (this.prop || this.name) + (this.mod || '') + '}';
        const castText = this.cast ? ('::' + this.cast) : '';
        const escapedName = npm.formatting.as.name(this.name);

        this.extendState({variable, castText, escapedName});
        Object.freeze(this);
    }
@class helpers.Column
@description

Read-only structure with details for a single column. Used primarily by {@link helpers.ColumnSet ColumnSet}.

The class parses details into a template, to be used for query generation.

@param {string|helpers.ColumnConfig} col
Column details, depending on the type.

When it is a string, it is expected to contain a name for both the column and the source property, assuming that the two are the same.
The name must adhere to JavaScript syntax for variable names. The name can be appended with any format modifier as supported by
{@link formatting.format as.format} (`^`, `~`, `#`, `:csv`, `:list`, `:json`, `:alias`, `:name`, `:raw`, `:value`), which is then removed from the name and put
into property `mod`. If the name starts with `?`, it is removed, while setting flag `cnd` = `true`.

If the string doesn't adhere to the above requirements, the method will throw {@link external:TypeError TypeError} = `Invalid column syntax`.

When `col` is a simple {@link helpers.ColumnConfig ColumnConfig}-like object, it is used as an input configurator to set all the properties
of the class.

@property {string} name
Destination column name + source property name (if `prop` is skipped). The name must adhere to JavaScript syntax for variables,
unless `prop` is specified, in which case `name` represents only the column name, and therefore can be any non-empty string.

@property {string} [prop]
Source property name, if different from the column's name. It must adhere to JavaScript syntax for variables.

It is ignored when it is the same as `name`.

@property {string} [mod]
Formatting modifier, as supported by method {@link formatting.format as.format}: `^`, `~`, `#`, `:csv`, `:list`, `:json`, `:alias`, `:name`, `:raw`, `:value`.

@property {string} [cast]
Server-side type casting, without `::` in front.

@property {boolean} [cnd]
Conditional column flag.

Used by methods {@link helpers.update update} and {@link helpers.sets sets}, ignored by methods {@link helpers.insert insert} and
{@link helpers.values values}. It indicates that the column is reserved for a `WHERE` condition, not to be set or updated.

It can be set from a string initialization, by adding `?` in front of the name.

@property {*} [def]
Default value for the property, to be used only when the source object doesn't have the property.
It is ignored when property `init` is set.

@property {helpers.initCB} [init]
Override callback for the value.

@property {helpers.skipCB} [skip]
An override for skipping columns dynamically.

Used by methods {@link helpers.update update} (for a single object) and {@link helpers.sets sets}, ignored by methods
{@link helpers.insert insert} and {@link helpers.values values}.

It is also ignored when conditional flag `cnd` is set.

@returns {helpers.Column}

@see
{@link helpers.ColumnConfig ColumnConfig},
{@link helpers.Column#castText castText},
{@link helpers.Column#escapedName escapedName},
{@link helpers.Column#variable variable}

@example

const pgp = require('pg-promise')({
    capSQL: true // if you want all generated SQL capitalized
});

const {Column} = pgp.helpers;

// creating a column from just a name:
const col1 = new Column('colName');
console.log(col1);
//=>
// Column {
//    name: "colName"
// }

// creating a column from a name + modifier:
const col2 = new Column('colName:csv');
console.log(col2);
//=>
// Column {
//    name: "colName"
//    mod: ":csv"
// }

// creating a column from a configurator:
const col3 = new Column({
    name: 'colName', // required
    prop: 'propName', // optional
    mod: '^', // optional
    def: 123 // optional
});
console.log(col3);
//=>
// Column {
//    name: "colName"
//    prop: "propName"
//    mod: "^"
//    def: 123
// }