#ifdef __cplusplus
extern "C"
{
#endif

#include "postgres.h" // 与 #include <iomanip> 冲突
#include "utils/palloc.h"
#include "utils/memutils.h"
#include "utils/memutils.h"
#include "nodes/pg_list.h"

#ifdef __cplusplus
}
#endif

#include "encryptsql/fieldmap.h"
#include "utils.h"
#include <json/json.h>
#include <string>
#include <fstream>
#include <vector>
#include <set>
#include <memory>
#include <algorithm>
#include <iostream>
#include <mutex>
#include "crypto/crypto.h"
#include "LogBase.h"

using std::cout;
using std::endl;
using std::make_shared;
using std::mutex;
using std::shared_ptr;
using std::string;
using std::transform;
using std::vector;

#define SHARED(x) shared_ptr<Json::Value>(x)
#define MAKE_SHARED(x) make_shared<Json::Value>(x)

// typedef enum {
//     SET_ONCE,
//     SET_FROM_TABLE,
//     SET_UNSET

// } CurrentNodeStatus;

class FieldMapper {
private:
	shared_ptr<Json::Value> root;                   //map.json文件的整体json结构
	string path;                                    //map.json文件路径
	mutable Json::Value *currentSchema = nullptr;   //当前的Schema，具体啥意思？
	mutable Json::Value *currentTable = nullptr;    //当前的Table，具体啥意思？
	Json::Value schemaDefaultValue;                 //schema的默认值，设置过后为{"map": {}}
	Json::Value tableDefaultValue;                  //table的默认值，设置过后为{"map": {}}
	Json::Value columnDefaultValue;                 //column的默认值，设置过后为{"cipher": []}
	int status;                                     //跟下面的enum类型相关，但具体说是啥意思？

	enum {
		SET_ONCE,
		SET_FROM_TABLE,
		SET_UNSET
	};

	std::vector<string> tables;                     //这是啥？ ---> 应该跟CurrentNode有关系，如果是create里面存的就是table名，但是创建下一个table的时候上一个就会删除

public:
	FieldMapper();

	FieldMapper(const string &path);

	~FieldMapper();

	Json::Value *getCurNodeBy(const string &tag, const string &key);

	string getValueBy(const string &tag, const string &key);

	void setValueBy(const string &tag, const string &key, const string &value);

	void setCurrentNodeOnce(string table = "", string schema = "");

	void setFromTable(const string &table);

	void setDefaultValue();

	void init();

	void setSysMapRelation();

	void setTableAlias(const string &tablename, const string &aliasname);

	string tableAliasTransform(string tablename);

	void cleanup();

	void save(string _path = "");

	void setFilteredSql(string sql);

	bool isFilteredSql(string sql) const;

	bool hasCipher(const string &column, T_Cipher t);

	int getStatus() const {
		return status;
	}

	void deleteNode(string table = "", string schema = "");

    void deleteColumn(const string &column);

	void addColumnAndType(const string &column, const string &_typename);

	void getTableColumns(char **cols, string table = "");

	void getColumnType(const string &col, char *v);

	size_t getTableColumnSize(string table = "") const;

	void setDefaultUDFMap();

	vector<T_Cipher> getColumnCipherArray(const string &column);

	//test only
	void printJson(const Json::Value &value) const; // 定义 printJson 函数
};

void FieldMapper::setDefaultUDFMap() {
}

size_t FieldMapper::getTableColumnSize(string table) const {
	auto oldTable = currentTable;
	if (table.size()) {
		currentTable = &currentSchema->operator[](table);
	}

	currentTable = oldTable;

	return currentTable->operator[]("columns").size();
}

/**
 * @brief 将明文列名和其对应的原类型加入map中
 *
 * 示例:
 * "test_table" :
 * {
 *     "columns" : [ "sno" ],    <----------- (1)
 *     "map" :
 *     {
 *         "column_ea0cedee63deb374" : "sno_AES",
 *         "sno_AES" : "column_ea0cedee63deb374"
 *     },
 *     "sno" :
 *     {
 *         "cipher" : [ 3 ],
 *         "type" : "int4"      <----------- (2)
 *     }
 * }
 *
 * @param[in] column 明文列名 e.g. "sno"
 * @param[in] _typename 该列原类型 e.g. "int4"
 *
 * @return null
 */
void FieldMapper::addColumnAndType(const string &column, const string &_typename) {
	auto table = tables.back();//q：有用？
	currentTable->operator[]("columns").append(column);
	//如果不存在会创建，因此在这里会创建"sno"和他的子列"type"
	currentTable->operator[](column)["type"] = _typename;
}

string FieldMapper::tableAliasTransform(string tablename) {
	return currentSchema->isMember(tablename) ? tablename : (*root)["tmp"]["tbltmp"]["alias"][tablename].asString();
}

FieldMapper::FieldMapper() {
}

void FieldMapper::setDefaultValue() {
	Json::CharReaderBuilder builder;
	builder["collectComments"] = true;
	std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
	const char baseContext[] = " {\"map\": {} } ";
	//将 baseContext 中的 JSON 数据解析并存储到 tableDefaultValue 中
	reader->parse(baseContext, baseContext + sizeof(baseContext), &tableDefaultValue, nullptr);
	//将 baseContext 中的 JSON 数据解析并存储到 schemaDefaultValue 中
	reader->parse(baseContext, baseContext + sizeof(baseContext), &schemaDefaultValue, nullptr);
	const char baseContext2[] = " {\"cipher\":[]} ";
	//将 baseContext2 中的 JSON 数据解析并存储到 schemaDefaultValue 中
	reader->parse(baseContext2, baseContext2 + sizeof(baseContext2), &columnDefaultValue, nullptr);
	if (root->operator[]("timestamp").isNull()) {
		root->operator[]("timestamp") = 0;
	}
	if (root->operator[]("udffunc").isNull() || (*root)["udffunc"]["map"].isNull()) {
		const char baseContext3[] = "{           \
                \"map\" : {                     \
                    \"*\" : \"smhe_multiply\",    \
                    \"+\" : \"sahe_add\",    \
                    \"-\" : \"sahe_sbustract\",    \
                    \"/\" : \"smhe_divide\",    \
                    \"<\" : \"ore_en_abs_lt\",     \
                    \"<=\" : \"ore_en_abs_le\",    \
                    \"<>\" : \"ore_en_abs_ne\",  \
                    \">\" : \"ore_en_abs_gt\",     \
                    \">=\" : \"ore_en_abs_ge\",    \
                    \"add\" : \"sahe_add\",  \
                    \"avg\" : \"avg\",          \
                    \"count\" : \"count\",      \
                    \"date_part\" : \"date_part\",  \
                    \"pow\" : \"smhe_pow\",  \
                    \"min\" : \"ore_min\",  \
                    \"max\" : \"ore_max\",  \
                    \"sum\" : \"sahe_sum\" }}}";
		reader->parse(baseContext3, baseContext3 + sizeof(baseContext3), &root->operator[]("udffunc"), nullptr);
	}
}

void FieldMapper::printJson(const Json::Value &value) const {
	Json::StreamWriterBuilder writer;
	writer["indentation"] = "  ";  // 设置缩进格式
	std::string jsonString = Json::writeString(writer, value);
	std::cout << jsonString << std::endl;
}


void FieldMapper::setSysMapRelation() {
	// 如果没有默认的系统表映射，则设置此映射

	////////////////////////////////////////////////////////////////
	///// Table pg_settings
	// setValueBy("table", "pg_settings", "pg_settings");
	// setFromTable("pg_settings");
	// setValueBy("column", "name", "name");
	// setValueBy("column", "setting", "setting");
	// setValueBy("column", "setting", "setting");

	// 设置一些过滤SQL
	setFilteredSql("select name, setting from pg_settings where name in ('connection_info')");
	setFilteredSql("select pg_backend_pid();");
	setFilteredSql("SELECT VERSION()");
	cleanup();
	// save();
}

/**
 * @brief 初始化 FieldMapper 对象，通过从文件加载配置数据。
 *
 * 该函数尝试打开指定的文件并将其 JSON 内容读取到 `root` 对象中。
 * 如果文件无法打开或内容无法解析，则会显示警告并使用默认值。
 * 该函数还初始化临时数据结构并设置当前模式。
 *
 * @details
 * - 打开由 `path` 指定的文件。
 * - 解析 JSON 内容并存储在 `root` 中。
 * - 初始化临时数据结构 `tmp.restmp` 和 `tmp.tbltmp`。
 * - 检查并初始化 `schema.public` 节点（如果为空）。
 * - 设置 `currentSchema` 指向 `root.schema.public`。
 * - 处理完后关闭文件。
 *
 * @note 此函数应在 FieldMapper 对象的初始化阶段调用。
 */
void FieldMapper::init() {
	// 打开文件，以读模式打开路径 `path` 指定的文件
	std::fstream fin(path, std::fstream::in);
	if (fin.is_open()) {
		Json::CharReaderBuilder builder;
		builder["collectComments"] = true;
		JSONCPP_STRING errs;
		// 如果文件已到达末尾或解析失败，打印警告信息
		if (fin.eof() || !parseFromStream(builder, fin, root.get(), &errs)) {
			std::cout << "来自 FieldMapper init() 的警告: " << errs << std::endl;
		}
	}
	// 初始化临时数据结构
	(*root)["tmp"]["restmp"] = {};
	(*root)["tmp"]["tbltmp"] = {};
	// 如果 `root.schema.public` 节点为空，则使用默认值进行初始化
	if ((*root)["schema"]["public"].isNull()) {
		(*root)["schema"]["public"] = Json::Value(schemaDefaultValue);
		setSysMapRelation();
		setDefaultValue();
	}
	// 设置当前模式
	currentSchema = &(*root)["schema"]["public"];
	// 关闭文件流
	fin.close();
}

FieldMapper::FieldMapper(const string &_path) {
	path = _path;
	root = MAKE_SHARED();
	init();
}

void FieldMapper::save(string _path) {
	// 先删除tmp节点，写完文件后再回复。
	// TODO: 多节点同时对元数据进行修改，会出问题
	auto tmp = (*root)["tmp"];
	root->removeMember("tmp");
	std::ofstream fout;
	if (_path.empty())
		fout.open(path);
	else
		fout.open(_path);

	if (!fout.is_open()) {
		LogError("error from FieldMapper save(): can not open %s", path.c_str());
		// std::cout << "error from FieldMapper save(): can not open " << _path << std::endl;
		std::cout << "error from FieldMapper save(): can not open " << path.c_str() << std::endl;
		abort();
	} else {
		Json::StreamWriterBuilder builder;
		builder["commentStyle"] = "None";
		std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
		writer->write(*root, &fout);
		fout << std::endl; // add lf and flush
	}
	fout.close();
	(*root)["tmp"] = tmp; // 不希望保存tmp下的数据，但是在解析一次SQL时可能调用save, 这样就会丢失别名数据.
}

FieldMapper::~FieldMapper() {
	// mapper...\n";
	// save();
}

Json::Value *FieldMapper::getCurNodeBy(const string &tag, const string &key) {
	// if (currentSchema && currentSchema->isNull()) {
	//     errmsg("node currentSchema is null\n");
	//     return nullptr;
	// }
	Json::Value *currentNode = nullptr;
	if (!tag.compare("table")) {
		currentNode = currentSchema;
	} else if (!tag.compare("column")) {
		if (status == SET_ONCE) {
			currentTable = &(*currentSchema)[tableAliasTransform(tables.back())];
			tables.pop_back();
			status = SET_FROM_TABLE; // 用过一次之后就变为Set from table
		} else if (status == SET_FROM_TABLE) {
			if (tables.size() == 1) {
				// 可能来自 create 只有一个table，就不需要搜索了
				currentTable = &(*currentSchema)[tableAliasTransform(tables.back())];
			} else {
				for (auto it: tables) {
					auto transfromed = tableAliasTransform(it);
					if (!(*currentSchema)[transfromed]["map"][key].isNull() ||
					    !(*currentSchema)[transfromed][key].isNull()) {
						currentTable = (&(*currentSchema)[it]);
						break;
					} else {
						(*currentSchema)[transfromed]["map"].removeMember(key);
						(*currentSchema)[transfromed].removeMember(key);
					}
				}
			}
		} else {
			// errmsg("Unknown mapper status: %d\n", status);
		}
		currentNode = currentTable;
	} else if (!tag.compare("restmp"))
		currentNode = &(*root)["tmp"]["restmp"];
	else if (!tag.compare("tbltmp"))
		currentNode = &(*root)["tmp"]["tbltmp"];
	else if (!tag.compare("udffunc"))
		currentNode = &(*root)["udffunc"];
	else
		currentNode = &(*root)["schema"];
	return currentNode;
}

string FieldMapper::getValueBy(const string &tag, const string &key) {
	// 根据tag不同，到对应的字段中寻找map
	auto currentNode = getCurNodeBy(tag, key);
	if (!currentNode)
		return (*root)["tmp"]["restmp"]["map"][key].isNull() ? "" : (*root)["tmp"]["restmp"]["map"][key].asString();
	auto res = (*currentNode)["map"][key];
	if (res.isNull()) { // 处理别名的情况
		(*currentNode)["map"].removeMember(key);
		// 在 targetList中，无法分辨target name是列名还是别名
		if (!tag.compare("table"))
			// 可能是table的别名
			res = (*root)["tmp"]["tbltmp"]["map"][key];
		else if (!tag.compare("column")) {
			// auto colname = key.substr(0, key.find_last_of("_")); ???
			res = (*root)["tmp"]["restmp"]["map"][key];
		}
	}
	return res.isNull() ? "" : res.asString();
}

/**
 * 未写完
 * @brief 根据tag的类型将相应的key v对，即明密文对存入map中
 *
 * 如果tag是table则创建默认的table子列并将table的明密文对映射存入外层map
 * 如果tag是column则向该node节点下的cipher中添加加密类型，并将column的明密文对存入内层(table)map
 *
 * @param[in] tag 当前类型 e.g. "table"
 * @param[in] key 明文 e.g. "example_table"
 * @param[in] v 与明文对应的密文名 e.g. "table_1b105edecc3bc987"
 *
 * @return null
 */
void FieldMapper::setValueBy(const string &tag, const string &key, const string &v) {
	// 可以多次设置， 自动覆盖原来的值
	// bidirection map
	if (!tag.compare("restmp")) {
		(*root)["tmp"]["restmp"]["map"][key] = v;
		(*root)["tmp"]["restmp"]["map"][v] = key;
		return;
	}
	auto currentNode = getCurNodeBy(tag, key);
	auto old_v = (*currentNode)["map"][key];
	if (!old_v.isNull()) {
		(*currentNode)["map"].removeMember(old_v.asString());
	}// 删除原来的值

	// 可能是整个public下的map，即table的map，也可能是某一个table下col的map，取决于currentNode
	(*currentNode)["map"][key] = v;
	(*currentNode)["map"][v] = key;

	/*将key以'_'为分界线分为两部分
	 * key = "table_abc"
	 * colname = "table"
	 * suffix = "abc"
	*/

	//q:为了解决select中解密时的map无法找到的问题在这里跳过NOCRYPT的操作，可能会有错误!
	if(key == v) {
		return;
	}

	auto delimiterIndex = key.find_last_of("_");
	string colname = key, suffix = "";
	if (delimiterIndex != key.npos) {
		colname = key.substr(0, delimiterIndex);
		suffix = key.substr(delimiterIndex + 1, key.size() - delimiterIndex - 1);
	}

	if (!tag.compare("table")) {
		(*currentNode)[key] = Json::Value(tableDefaultValue);
	} else if (!tag.compare("column")) {
		int cipher = string2TypeCipher(suffix.c_str());

		/**
		* "test_table" :
 		* {
 		*     "columns" : [ "sno" ],
 		*     "map" :
 		*     {
 		*         "column_ea0cedee63deb374" : "sno_AES",
 		*         "sno_AES" : "column_ea0cedee63deb374"
 		*     },
 		*     "sno" :					<----------- this
 		*     {
 		*         "cipher" : [ 3 ],		<----------- this
 		*         "type" : "int4"
 		*     }
 		* }
		*/
		if ((*currentNode)[colname].isNull()) { //如果是空的，就新建一个column，如果不是就进行append
			(*currentNode)[colname] = Json::Value(columnDefaultValue);
			// if (cipher != CIPHER_NOCRYPT)
			(*currentNode)[colname]["cipher"].append(cipher);
		} else // 往cipherArray 中添加cipher
		{
			auto cipherArray = (*currentNode)[colname]["cipher"];
			auto it = cipherArray.begin();
			for (; it != cipherArray.end(); ++it) {
				if (it->asInt() == cipher)
					break;
			}
			if (it == cipherArray.end()) {
				(*currentNode)[colname]["cipher"].append(cipher);
			}
		}
	} else if (!tag.compare("schema"))
		(*currentNode)[key] = Json::Value(schemaDefaultValue);
	// save();
}

void FieldMapper::setCurrentNodeOnce(string table, string schema) {
	status = SET_ONCE;
	if (!schema.empty()) {
		if ((*root)["schema"][schema].isNull()) {
			(*root)["schema"][schema] = Json::Value(schemaDefaultValue);
		}
		currentSchema = &(*root)["schema"][schema];
	}
	if (!table.empty()) {
		tables.push_back(table);
	}
}

void FieldMapper::deleteNode(string table, string schema) {
	if (!schema.empty()) {
		(*root)["schema"].removeMember(schema);
		auto v = (*root)["schema"]["map"][schema].asString();
		(*root)["schema"]["map"].removeMember(schema);
		(*root)["schema"]["map"].removeMember(v);
	}

	if (!table.empty()) {
		(*currentSchema).removeMember(table);
		auto v = (*currentSchema)["map"][table].asString();
		(*currentSchema)["map"].removeMember(table);
		(*currentSchema)["map"].removeMember(v);
	}
	cleanup();
	save();
}

void FieldMapper::deleteColumn(const string &column) {
    // 1. 从"columns"数组中删除列名
    Json::Value& columnsArray = currentTable->operator[]("columns");
    Json::Value newColumns(Json::arrayValue);
    for (const auto& col : columnsArray) {
        if (col.asString() != column) {
            newColumns.append(col);
        }
    }
    (*currentTable)["columns"] = newColumns;

    // 2. 删除以该列名为键的对象
    currentTable->removeMember(column);

    // 3. 从map中删除相关的映射
    Json::Value& mapObject = (*currentTable)["map"];
    vector<string> keysToRemove;

    // 3.1 找出所有需要删除的键
    for (const auto& key : mapObject.getMemberNames()) {
        string value = mapObject[key].asString();
        // 如果键或值以column_开头，或者包含该列名，则需要删除
        if (key.find(column + "_") == 0 || value.find(column + "_") == 0 ||
            key == column || value == column) {
            keysToRemove.push_back(key);
            keysToRemove.push_back(value); // 同时删除反向映射
        }
    }

    // 3.2 删除找到的所有键
    for (const auto& key : keysToRemove) {
        mapObject.removeMember(key);
    }

    cleanup(); // 清理状态
    save();    // 保存更改
}

void FieldMapper::setFromTable(const string &table) {
	status = SET_FROM_TABLE;
	tables.push_back(table);
	currentTable = &currentSchema->operator[](table);
}

void FieldMapper::setTableAlias(const string &tablename, const string &aliasname) {
	(*root)["tmp"]["tbltmp"]["alias"][tablename] = aliasname;
	(*root)["tmp"]["tbltmp"]["alias"][aliasname] = tablename;
}

void FieldMapper::cleanup() {
	tables.clear();
	status = SET_UNSET;
	currentTable = nullptr;
	currentSchema = &(*root)["schema"]["public"];
}

void FieldMapper::setFilteredSql(string sql) {
	transform(sql.begin(), sql.end(), sql.begin(), tolower);
	(*root)["filteredSql"][sql] = 1;
}

bool FieldMapper::isFilteredSql(string sql) const {
	transform(sql.begin(), sql.end(), sql.begin(), tolower);
	if ((*root)["filteredSql"][sql].isNull()) {
		(*root)["filteredSql"].removeMember(sql);
		return false;
	}
	return true;
}

bool FieldMapper::hasCipher(const string &column, T_Cipher t) {
	vector<T_Cipher> &&ciphers = getColumnCipherArray(column);
	for (auto &it: ciphers) {
		if (it == t)
			return true;
	}
	return false;
};

vector<T_Cipher> FieldMapper::getColumnCipherArray(const string &column) {
	string &topTable = tables.back(); // 先记录下栈顶的表
	auto statusOld = status;
	auto currentNode = *getCurNodeBy("column", column);
	auto cipherArray = currentNode[column]["cipher"];
	if (statusOld == SET_ONCE) {
		setCurrentNodeOnce(topTable);
	}
	vector<T_Cipher> vectorCipherArray;
	vectorCipherArray.resize(cipherArray.size());
	for (int i = 0; i < cipherArray.size(); ++i) {
		vectorCipherArray[i] = (T_Cipher) cipherArray[i].asInt();
	}
	return vectorCipherArray;
}

void FieldMapper::getTableColumns(char **cols, string table) {

	auto oldTable = currentTable;

	if (table.size())
		currentTable = &currentSchema->operator[](table);

	for (int i = 0; i < currentTable->operator[]("columns").size(); i++) {
		auto columns = currentTable->operator[]("columns");
		auto column = columns[i].asCString();
		strcpy(cols[i], column);
	}

	currentTable = oldTable;
}

void FieldMapper::getColumnType(const string &col, char *v) {
	auto curNode = getCurNodeBy("column", col);
	if (!curNode) {
		v[0] = '\0';
		return;
	}
	auto res = curNode->operator[](col)["type"];
	if (res.isNull())
		return;
	auto type = res.asCString();
	strcpy(v, type);
}

static thread_local std::unique_ptr<FieldMapper> mapper; // 线程局部存储

static std::mutex save_mutex;
////////////////////////////////////////
//// C API Wrapper
////////////////////////////////////////

int getMapperStatus() {
	return mapper->getStatus();
}

void initCheck() {
	if (!mapper) {
		cout << "mapper is not init\n";
		exit(-1);
	}
}

void mapperSave() {
	{
		std::unique_lock<std::mutex>(save_mutex); //TODO: 尝试优化
		mapper->save();
	}
}

void getValueBy(const char *tag, const char *key, char *val) {
	initCheck();
	string res = mapper->getValueBy(tag, key);
	sprintf(val, "%s", res.c_str());
}

void setValueBy(const char *tag, const char *key, const char *v) {
	initCheck();
	mapper->setValueBy(tag, key, v);
}

void setCurrentNodeOnce(const char *table, const char *schema) {
	mapper->setCurrentNodeOnce(table, schema);
}

void setFromTable(const char *table) {
	mapper->setFromTable(table);
}

void setTableAlias(const char *tablename, const char *aliasname) {
	mapper->setTableAlias(tablename, aliasname);
}

void mapperInit(const char *path) {
	mapper.reset(new FieldMapper(path));
}

void mapperCleanup() {
	mapper->cleanup();
}

bool hasCipher(const char *column, T_Cipher t) {
	return mapper->hasCipher(column, t);
}

const char *plainDataType2String(PlainDataType t) {
	switch (t) {
		case T_STRING_CATALOG:
			return "catalog";
		case T_STRING_TABLE:
			return "table";
		case T_STRING_COLUMN:
			return "column";
		case T_STRING_SCHEMA:
			return "schema";
		case T_STRING_UDF_FUNCTION:
			return "udffunc";
		case T_STRING_RESTMP:
			return "restmp";
		case T_STRING_TBLTMP:
			return "tbltmp";
		default:
			return "others";
	}
}

bool isFilteredSql(const char *sql) {
	return mapper->isFilteredSql(sql);
}

void deleteNode(const char *table, const char *schema) {
	mapper->deleteNode(table, schema);
}

void deleteColumn(const char *column) {
    mapper->deleteColumn(column);
}

void addColumnAndType(const char *column, const char *_typename) {
	mapper->addColumnAndType(column, _typename);
}

void getFirstTableColumnsAlloc(char ***cols, int *size) // 此函数自动分配内存， 获取指定table的所有columns
{
	*size = mapper->getTableColumnSize();

	*cols = (char **) palloc(sizeof(char *) * *size);
	for (size_t i = 0; i < *size; i++)
		(*cols)[i] = (char *) palloc0(Short_Buffer_Size);
	mapper->getTableColumns(*cols, "");
}

void getColumnType(const char *col, char *v) // 获取指定col的type
{
	mapper->getColumnType(col, v);
}

void getColumnCiphers(const char *col, T_Cipher *ciphers, int *size) // 需要自行分配内存，获取指定col的加密方式, 并且sort
{
	auto vectCiphers = mapper->getColumnCipherArray(col);
	*size = vectCiphers.size();
	for (size_t i = 0; i < *size; i++)
		ciphers[i] = vectCiphers[i];
	std::sort(ciphers, ciphers + *size);
}

ColumnInfo *getColumnInfoAlloc(const char *col) // 内存自动分配，获取指定列的信息
{
	ColumnInfo *cinfo = (ColumnInfo *) palloc(sizeof(ColumnInfo));
	cinfo->type = (char *) palloc(Short_Buffer_Size);
	cinfo->name = (char *) palloc(Short_Buffer_Size);
	strcpy(cinfo->name, col);
	getColumnType(col, cinfo->type);
	T_Cipher ciphers[CIPHER_COUNT];
	int nCipher = 0;
	getColumnCiphers(col, ciphers, &nCipher);
	cinfo->ciphers = (T_Cipher *) palloc(sizeof(T_Cipher) * nCipher);
	cinfo->len = nCipher;
	std::copy(ciphers, ciphers + nCipher, cinfo->ciphers);

	return cinfo;
}

void getFirstTableAllColumnsInfoAlloc(ColumnInfo ***pinfos, int *size) // 内存自动分配，获取所有的指定table(默认最后入栈的table下)的所有的
{
	char **cols;
	int nColumn = 0;
	getFirstTableColumnsAlloc(&cols, &nColumn);

	if (nColumn) {
		ColumnInfo **infos = (ColumnInfo **) palloc(sizeof(ColumnInfo *) * nColumn);
		*pinfos = infos;
		for (size_t i = 0; i < nColumn; i++) {
			char *col = cols[i];
			infos[i] = getColumnInfoAlloc(col);
		}
	}
	*size = nColumn;
}

void getSpecifyColumnsInfoAlloc(List *cols, ColumnInfo ***pinfos) { // 内存自动分配, 获取指定列的信息.
	ListCell *cell;
	ColumnInfo **infos = (ColumnInfo **) palloc(sizeof(ColumnInfo *) * cols->length);
	*pinfos = infos;

	int i = 0;
	foreach (cell, cols) {
		infos[i++] = getColumnInfoAlloc(strVal((Value *) lfirst(cell)));
	}
}

size_t getFirstTableColumnSize() {
	return mapper->getTableColumnSize();
}
