static gpointer
gda_sql_statement_update_copy (gpointer src)
{
	GdaSqlStatementUpdate *dest;
	GdaSqlStatementUpdate *update = (GdaSqlStatementUpdate *) src;
	GSList *list;

	dest = gda_sql_statement_update_new ();
	if (update->on_conflict)
                dest->on_conflict = g_strdup (update->on_conflict);

	dest->table = gda_sql_table_copy (update->table);
	gda_sql_any_part_set_parent (dest->table, dest);

	for (list = update->fields_list; list; list = list->next) {
		dest->fields_list = g_slist_prepend (dest->fields_list,
						     gda_sql_field_copy ((GdaSqlField *) list->data));
		gda_sql_any_part_set_parent (dest->fields_list->data, dest);
	}
	dest->fields_list = g_slist_reverse (dest->fields_list);

	for (list = update->expr_list; list; list = list->next) {
		dest->expr_list = g_slist_prepend (dest->expr_list,
						   gda_sql_expr_copy ((GdaSqlExpr *) list->data));
		gda_sql_any_part_set_parent (dest->expr_list->data, dest);
	}
	dest->expr_list = g_slist_reverse (dest->expr_list);

	dest->cond = gda_sql_expr_copy (update->cond);
	gda_sql_any_part_set_parent (dest->cond, dest);

	return dest;
}
/**
 * gda_sql_case_copy
 * @sc: a #GdaSqlCase structure to be copied
 *
 * Creates a new #GdaSqlCase structure initiated with the values stored in @sc.
 *
 * Returns: a new #GdaSqlCase structure.
 */
GdaSqlCase *
gda_sql_case_copy (GdaSqlCase *sc)
{
	GdaSqlCase *copy;
	GSList *list;

	if (!sc) return NULL;

	copy = gda_sql_case_new (NULL);
	copy->base_expr = gda_sql_expr_copy (sc->base_expr);
	gda_sql_any_part_set_parent (copy->base_expr, copy);
	copy->else_expr = gda_sql_expr_copy (sc->else_expr);
	gda_sql_any_part_set_parent (copy->else_expr, copy);

	for (list = sc->when_expr_list; list; list = list->next) {
		copy->when_expr_list = g_slist_prepend (copy->when_expr_list,
							gda_sql_expr_copy ((GdaSqlExpr*) list->data));
		gda_sql_any_part_set_parent (copy->when_expr_list->data, copy);
	}

	copy->when_expr_list = g_slist_reverse (copy->when_expr_list);
	for (list = sc->then_expr_list; list; list = list->next) {
		copy->then_expr_list = g_slist_prepend (copy->then_expr_list,
						       gda_sql_expr_copy ((GdaSqlExpr*) list->data));
		gda_sql_any_part_set_parent (copy->then_expr_list->data, copy);
	}
	copy->then_expr_list = g_slist_reverse (copy->then_expr_list);

	return copy;
}
static gpointer
gda_sql_statement_unknown_copy (gpointer src)
{
	GdaSqlStatementUnknown *dest;
	GSList *list;
	GdaSqlStatementUnknown *unknown = (GdaSqlStatementUnknown *) src;

	dest = gda_sql_statement_unknown_new ();
	for (list = unknown->expressions; list; list = list->next) {
		dest->expressions = g_slist_prepend (dest->expressions, 
						     gda_sql_expr_copy ((GdaSqlExpr*) list->data));
		gda_sql_any_part_set_parent (dest->expressions->data, dest);
	}
	dest->expressions = g_slist_reverse (dest->expressions);
	return dest;
}
/**
 * gda_sql_select_order_copy
 * @order: a #GdaSqlSelectOrder structure to be copied
 *
 * Creates a new #GdaSqlSelectOrder structure initiated with the values stored in @order.
 *
 * Returns: a new #GdaSqlSelectOrder structure.
 */
GdaSqlSelectOrder *
gda_sql_select_order_copy (GdaSqlSelectOrder *order)
{
	GdaSqlSelectOrder *copy;

	if (!order) return NULL;

	copy = gda_sql_select_order_new (NULL);

	copy->expr = gda_sql_expr_copy (order->expr);
	gda_sql_any_part_set_parent (copy->expr, copy);

	if (order->collation_name)
		copy->collation_name = g_strdup (order->collation_name);
	copy->asc = order->asc;
	return copy;
}
gpointer
_gda_sql_statement_select_copy (gpointer src)
{
	GdaSqlStatementSelect *dest;
	GdaSqlStatementSelect *select = (GdaSqlStatementSelect *) src;
	GSList *list;

	dest = gda_sql_statement_select_new ();
	dest->distinct = select->distinct;

	dest->distinct_expr = gda_sql_expr_copy (select->distinct_expr);
	gda_sql_any_part_set_parent (dest->distinct_expr, dest);

	for (list = select->expr_list; list; list = list->next) {
		dest->expr_list = g_slist_prepend (dest->expr_list,
						   gda_sql_select_field_copy ((GdaSqlSelectField*) list->data));
		gda_sql_any_part_set_parent (dest->expr_list->data, dest);
	}
	dest->expr_list = g_slist_reverse (dest->expr_list);

	dest->from = gda_sql_select_from_copy (select->from);
	gda_sql_any_part_set_parent (dest->from, dest);

	dest->where_cond = gda_sql_expr_copy (select->where_cond);
	gda_sql_any_part_set_parent (dest->where_cond, dest);

	for (list = select->group_by; list; list = list->next) {
		dest->group_by = g_slist_prepend (dest->group_by,
						  gda_sql_expr_copy ((GdaSqlExpr*) list->data));
		gda_sql_any_part_set_parent (dest->group_by->data, dest);
	}
	dest->group_by = g_slist_reverse (dest->group_by);

	dest->having_cond = gda_sql_expr_copy (select->having_cond);
	gda_sql_any_part_set_parent (dest->having_cond, dest);

	for (list = select->order_by; list; list = list->next) {
		dest->order_by = g_slist_prepend (dest->order_by,
						  gda_sql_select_order_copy ((GdaSqlSelectOrder*) list->data));
		gda_sql_any_part_set_parent (dest->order_by->data, dest);
	}
	dest->order_by = g_slist_reverse (dest->order_by);

	dest->limit_count = gda_sql_expr_copy (select->limit_count);
	gda_sql_any_part_set_parent (dest->limit_count, dest);

	dest->limit_offset = gda_sql_expr_copy (select->limit_offset);
	gda_sql_any_part_set_parent (dest->limit_offset, dest);

	return dest;
}
static gpointer
gda_sql_statement_insert_copy (gpointer src)
{
	GdaSqlStatementInsert *dest;
	GSList *list;
	GdaSqlStatementInsert *insert = (GdaSqlStatementInsert *) src;

	dest = gda_sql_statement_insert_new ();
	if (insert->on_conflict)
		dest->on_conflict = g_strdup (insert->on_conflict);

	dest->table = gda_sql_table_copy (insert->table);
	gda_sql_any_part_set_parent (dest->table, dest);
	
	for (list = insert->fields_list; list; list = list->next) {
		dest->fields_list = g_slist_prepend (dest->fields_list, 
						     gda_sql_field_copy ((GdaSqlField*) list->data));
		gda_sql_any_part_set_parent (dest->fields_list->data, dest);
	}
	dest->fields_list = g_slist_reverse (dest->fields_list);

	for (list = insert->values_list; list; list = list->next) {
		GSList *vlist, *clist = NULL;
		for (vlist = (GSList *) list->data; vlist; vlist = vlist->next) {
			clist = g_slist_prepend (clist,
						 gda_sql_expr_copy ((GdaSqlExpr*) vlist->data));
			gda_sql_any_part_set_parent (clist->data, dest);
		}
		dest->values_list = g_slist_append (dest->values_list, g_slist_reverse (clist));
	}
	if (insert->select) {
		if (GDA_SQL_ANY_PART (insert->select)->type == GDA_SQL_ANY_STMT_SELECT)
			dest->select = _gda_sql_statement_select_copy (insert->select);
		else if (GDA_SQL_ANY_PART (insert->select)->type == GDA_SQL_ANY_STMT_COMPOUND)
			dest->select = _gda_sql_statement_compound_copy (insert->select);
		else
			g_assert_not_reached ();
		gda_sql_any_part_set_parent (dest->select, dest);
	}

	return dest;
}
/**
 * gda_sql_operation_copy
 * @operation: a #GdaSqlOperation structure to be copied
 *
 * Creates a new #GdaSqlOperation structure initiated with the values stored in @operation.
 *
 * Returns: a new #GdaSqlOperation structure.
 */
GdaSqlOperation *
gda_sql_operation_copy (GdaSqlOperation *operation)
{
	GdaSqlOperation *copy;
	GSList *list;

	if (!operation) return NULL;

	copy = gda_sql_operation_new (NULL);
	copy->operator_type = operation->operator_type;

	for (list = operation->operands; list; list = list->next) {
		copy->operands = g_slist_prepend (copy->operands,
						  gda_sql_expr_copy ((GdaSqlExpr*) list->data));
		gda_sql_any_part_set_parent (copy->operands->data, copy);
	}
	copy->operands = g_slist_reverse (copy->operands);

	return copy;
}
/**
 * gda_sql_select_target_copy
 * @target: a #GdaSqlSelectTarget structure to be copied
 *
 * Creates a new #GdaSqlSelectTarget structure initiated with the values stored in @target.
 *
 * Returns: a new #GdaSqlSelectTarget structure.
 */
GdaSqlSelectTarget *
gda_sql_select_target_copy (GdaSqlSelectTarget *target)
{
	GdaSqlSelectTarget *copy;

	if (!target) return NULL;

	copy = gda_sql_select_target_new (NULL);
	copy->expr = gda_sql_expr_copy (target->expr);
	gda_sql_any_part_set_parent (copy->expr, copy);

	if (target->table_name)
		copy->table_name = g_strdup (target->table_name);
	if (target->as)
		copy->as = g_strdup (target->as);

	copy->validity_meta_object = target->validity_meta_object;

	return copy;
}
/**
 * gda_sql_function_copy
 * @function: a #GdaSqlFunction structure to be copied
 *
 * Creates a new #GdaSqlFunction structure initiated with the values stored in @function.
 *
 * Returns: a new #GdaSqlFunction structure.
 */
GdaSqlFunction *
gda_sql_function_copy (GdaSqlFunction *function)
{
	GdaSqlFunction *copy;

	if (!function) return NULL;

	copy = gda_sql_function_new (NULL);
	if (function->function_name)
		copy->function_name = g_strdup (function->function_name);

	if (function->args_list) {
		GSList *list;
		for (list = function->args_list; list; list = list->next) {
			copy->args_list = g_slist_prepend (copy->args_list,
							   gda_sql_expr_copy ((GdaSqlExpr *) list->data));
			gda_sql_any_part_set_parent (copy->args_list->data, copy);
		}
		copy->args_list = g_slist_reverse (copy->args_list);
	}

	return copy;
}
/**
 * gda_sql_select_field_copy
 * @field: a #GdaSqlSelectField structure to be copied
 *
 * Creates a new #GdaSqlSelectField structure initiated with the values stored in @field.
 *
 * Returns: a new #GdaSqlSelectField structure.
 */
GdaSqlSelectField *
gda_sql_select_field_copy (GdaSqlSelectField *field)
{
	GdaSqlSelectField *copy;

	if (!field) return NULL;

	copy = gda_sql_select_field_new (NULL);
	copy->expr = gda_sql_expr_copy (field->expr);
	gda_sql_any_part_set_parent (copy->expr, copy);

	if (field->field_name)
		copy->field_name = g_strdup (field->field_name);
	if (field->table_name)
		copy->table_name = g_strdup (field->table_name);
	if (field->as)
		copy->as = g_strdup (field->as);

	copy->validity_meta_object = field->validity_meta_object;
	copy->validity_meta_table_column = field->validity_meta_table_column;

	return copy;
}
/**
 * gda_sql_select_join_copy
 * @join: a #GdaSqlSelectJoin structure to be copied
 *
 * Creates a new #GdaSqlSelectJoin structure initiated with the values stored in @join.
 *
 * Returns: a new #GdaSqlSelectJoin structure.
 */
GdaSqlSelectJoin *
gda_sql_select_join_copy (GdaSqlSelectJoin *join)
{
	GdaSqlSelectJoin *copy;
	GSList *list;

	if (!join) return NULL;

	copy = gda_sql_select_join_new (NULL);
	copy->type = join->type;
	copy->position = join->position;

	copy->expr = gda_sql_expr_copy (join->expr);
	gda_sql_any_part_set_parent (copy->expr, copy);

	for (list = join->use; list; list = list->next) {
		copy->use = g_slist_prepend (copy->use,
					       gda_sql_field_copy ((GdaSqlField*) list->data));
		gda_sql_any_part_set_parent (copy->use->data, copy);
	}
	copy->use = g_slist_reverse (copy->use);

	return copy;
}