#include "PgAttributeContainer.h"
#include "Pgsql_Col.h"
#include "PgDatabaseCatalog.h"

//SELECT attname, pg_get_expr(adbin, adrelid) AS def_value
//FROM pg_attribute
// JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum
//WHERE atthasdef=true

std::string PgAttributeContainer::getLoadQuery() const
{
	std::string q = R"__(
SELECT attrelid, attname, atttypid, attstattarget,
	attnum, attndims, atttypmod, attnotnull, atthasdef, attisdropped,
    attislocal, attcollation, attacl, attoptions, pg_get_expr(def.adbin, def.adrelid) AS def_value,
    cs.relname AS sername, ns.nspname AS serschema, d.description)__";
	if (m_catalog.serverVersion() >= 100000)
		q += ", attidentity";
    if (m_catalog.serverVersion() >= 120000)
        q += ", attgenerated";
    q += R"__(
  FROM pg_catalog.pg_attribute AS att
	LEFT JOIN pg_attrdef AS def ON attrelid=adrelid AND attnum=adnum
	LEFT JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
    LEFT JOIN pg_namespace ns ON ns.oid=cs.relnamespace
    LEFT JOIN pg_catalog.pg_description AS d ON (objoid=attrelid AND d.objsubid=attnum) )__";

	return q;
}

PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row)
{
	Pgsql::Col col(row);
	PgAttribute v;
	col >> v.relid >> v.name >> v.typid >> v.stattarget
			>> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.isdropped
			>> v.islocal >> v.collation >> v.acl >> v.options >> v.defaultValue
            >> v.sername >> v.serschema >> v.description;
	if (m_catalog.serverVersion() >= 100000)
		col >> v.identity;
    if (m_catalog.serverVersion() >= 120000)
        col >> v.generated;

	return v;
}

std::vector<PgAttribute> PgAttributeContainer::getColumnsForRelation(Oid oid) const
{
	std::vector<PgAttribute> result;
	for (const auto &e : m_container)
		if (e.relid == oid)
			result.push_back(e);
	return result;
}
