LQ Newbie
Registered: Oct 2009
Posts: 3
Rep:
|
URGENT : *** glibc detected *** : double free or corruption (fasttop)
I am trying to migrate one of old C class from Solaris to RHEL5 with gcc version 4.1.2. I have no experience on C but need to get this done to have my system working. The C program is been working fine on solaris for last couple of years and now when I ported this to linux and run, i get this error "*** glibc detected *** : double free or corruption (fasttop)".
I have copied the code below, but found out by debuging that if I comment the 2 lines with free() command as shown, the error goes away, but this causes other errors while execution of the code. Any help on how I can fix this issue will be highly appreciated.
fprintf (stderr, "\nInside parse_sql - Before free:%s \n\n", "test");
free (l_st_coldata);
free (l_st_datafmt);
fprintf (stderr, "\nInside parse_sql - After free:%s \n\n", "test");
------------------------------------------------------------------------
#include <stdio.h>
#include <ctpublic.h>
#include <time.h>
#include <signal.h>
#include <sys/utsname.h>
#include "generic.h"
/* add new includes for LINUX */
#include <string.h>
#include <stdlib.h>
/* Global structures */
CS_CONTEXT *g_st_context;
CS_CONNECTION *g_st_dstconn;
CS_CONNECTION *g_st_srcconn;
int g_i_rows;
char g_s_ins_string[MAXSQL];
/* Global variables */
FILE *g_fp_errfile;
char g_s_update_sql[MAXSQL];
char g_s_indexcols[MAXSTRING];
char g_s_nullflag[MAXSTRING];
/* Local functions prototypes */
void fun_process();
int fun_parsql();
int fun_sourcesql();
int fun_get_ins_data();
int fun_ins_tmptable();
void fun_exit();
EX_COLDATA *f_fetch_data();
/*
** Function to execute the parameter query on Destination server
** and replace output values into Original query
*/
int fun_parsql (p_st_cmd, p_s_sql, p_s_parsql, p_s_tmp )
CS_COMMAND *p_st_cmd;
char p_s_sql[MAXSQL];
char p_s_parsql[MAXSQL];
char p_s_tmp[3000];
{
int l_i_return = 0, i = 0;
CS_INT l_i_res_type;
EX_COLDATA *l_st_coldata;
CS_DATAFMT *l_st_datafmt;
char *l_s_ptr;
char l_s_str[MAXSQL];
memset (l_s_str, 0, sizeof (l_s_str));
fprintf (stderr, "\nInside parse_sql:%s \n\n", "test");
/* Check if the original sql has two @ markers */
l_s_ptr = (char *) strchr (p_s_sql, '@');
if ((l_s_ptr == NULL) || ((char *) strrchr (p_s_sql, '@')) == l_s_ptr) {
f_errorlog ("Sql query should have @...@ syntax if you specify a parameter query");
return -1;
}
/* Prepare the cmd */
if ((l_i_return = f_prepare_sql (p_st_cmd, p_s_parsql)) != CS_SUCCEED)
return l_i_return;
/* Get the results */
while ((l_i_return = ct_results(p_st_cmd, &l_i_res_type)) == CS_SUCCEED) {
switch ((int)l_i_res_type) {
case CS_CMD_SUCCEED : break;
case CS_CMD_DONE : break;
case CS_CMD_FAIL : f_errorlog ("fun_parsql: ct_results failed");
return CS_FAIL;
break;
case CS_PARAM_RESULT : break;
case CS_ROW_RESULT :
if ((l_st_coldata = (EX_COLDATA *) f_fetch_data (p_st_cmd, l_st_datafmt, l_st_coldata, 0)) == NULL)
{
ct_cancel(NULL, p_st_cmd, CS_CANCEL_ALL);
return l_i_return;
}
break;
default : return CS_FAIL;
break;
}
}
switch ((int)l_i_return) {
case CS_END_RESULTS : l_i_return = CS_SUCCEED;
break;
case CS_FAIL : f_errorlog("fun_parsql: ct_results() failed");
break;
default : break;
}
/* Get first @ marker */
for (i=0; *p_s_sql != '@'; p_s_sql++, i++)
l_s_str[i] = *p_s_sql;
/* Substitute parameter value in the sql */
strcat (l_s_str, l_st_coldata->value);
/* Go to next @ marker */
for (p_s_sql++; *p_s_sql != '@'; p_s_sql++) ;
i += strlen (l_st_coldata->value);
/* Append the remaining sql in the original sql */
while (*++p_s_sql)
l_s_str[i++] = *p_s_sql;
l_s_str[++i] = '\0';
strcpy (p_s_tmp, l_s_str);
fprintf (stderr, "\nInside parse_sql - Before free:%s \n\n", "test");
free (l_st_coldata);
free (l_st_datafmt);
fprintf (stderr, "\nInside parse_sql - After free:%s \n\n", "test");
return l_i_return;
}
/*
** This executes the Original sql query on Source server
*/
int fun_sourcesql (p_st_cmd, p_st_dstcmd, p_s_sql, p_i_flag)
CS_COMMAND *p_st_cmd;
CS_COMMAND *p_st_dstcmd;
char *p_s_sql;
int p_i_flag;
{
int l_i_return = 0, i = 0;
CS_INT l_i_res_type;
EX_COLDATA *l_st_coldata;
CS_DATAFMT *l_st_datafmt;
/* Prepare the cmd */
if ((l_i_return = f_prepare_sql (p_st_cmd, p_s_sql)) != CS_SUCCEED) {
return l_i_return;
}
/* Get the results */
while ((l_i_return = ct_results(p_st_cmd, &l_i_res_type)) == CS_SUCCEED) {
switch ((int)l_i_res_type) {
case CS_CMD_SUCCEED : break;
case CS_CMD_DONE : break;
case CS_CMD_FAIL : f_errorlog ("fun_sourcesql: ct_results failed");
return CS_FAIL;
break;
case CS_ROW_RESULT :
if ((l_i_return = fun_get_ins_data (p_st_cmd, p_st_dstcmd, p_i_flag)) \
!= CS_SUCCEED ) {
ct_cancel(NULL, p_st_cmd, CS_CANCEL_ALL);
return l_i_return;
}
break;
default : return CS_FAIL;
break;
}
}
switch ((int)l_i_return) {
case CS_END_RESULTS:
/* Everything went fine */
l_i_return = CS_SUCCEED;
break;
case CS_FAIL:
/* ct_results() call failed */
f_errorlog("fun_sourcesql: ct_results() failed");
break;
default:
/* We got an unexpected return value */
break;
}
return l_i_return;
}
/*
** Important function in this program. It executes the Original sql query on Source server
** gets individual column datatypes, names and lengths. Then it creates temporary table
** by the name #tmp, inserts data into this table.
**
** If UPDATE flag is specified then it also builds final sql or final update clause that is
** executed later in main () itself.
*/
int fun_get_ins_data(p_st_cmd, p_st_dstcmd, p_upd_flag)
CS_COMMAND *p_st_cmd;
CS_COMMAND *p_st_dstcmd;
int p_upd_flag;
{
CS_RETCODE l_i_retcode;
CS_INT l_i_num_cols, i, j, l_i_rows_read = 0;
CS_DATAFMT *l_st_datafmt;
EX_COLDATA *l_st_coldata;
char l_s_sql[MAXSQL], l_s_datatype[MAXSTRING], l_s_strnull[MAXSTRING];
char l_s_tmp[MAXSQL], l_s_upd[MAXSQL], l_s_ins[MAXSQL];
int l_i_orig_datatype[100], l_i_row_count;
char *p;
fprintf (stderr, "\nconnect server 8:%s \n\n", "test");
/* Find out how many columns there are in this result set. */
if ((l_i_retcode = ct_res_info(p_st_cmd, CS_NUMDATA, &l_i_num_cols, CS_UNUSED, NULL)) != CS_SUCCEED) {
f_errorlog ("fun_get_ins_data: ct_res_info failed ...");
return -1;
}
if (l_i_num_cols <= 0) {
f_errorlog ("fun_get_ins_data: Zero columns returned...");
return -1;
}
f_errorlog ("Done til here...");
l_st_coldata = (EX_COLDATA *)malloc(l_i_num_cols * sizeof (EX_COLDATA));
if (l_st_coldata == NULL) {
f_errorlog ("fun_get_ins_data: Cannot malloc for coldata stuct...");
return -1;
}
fprintf (stderr, "\nconnect server 9:%s \n\n", "test");
l_st_datafmt = (CS_DATAFMT *)malloc(l_i_num_cols * sizeof (CS_DATAFMT));
if (l_st_datafmt == NULL) {
f_errorlog ("fun_get_ins_data: Cannot malloc for datafmt stuct...");
free(l_st_coldata);
return -1;
}
memset (l_s_sql, 0, sizeof (l_s_sql));
strcpy (l_s_sql, " create table #tmp ( \n");
for (i = 0; i < l_i_num_cols; i++) {
l_i_retcode = ct_describe(p_st_cmd, (i + 1), &l_st_datafmt[i]);
if (l_i_retcode != CS_SUCCEED) {
f_errorlog ("fun_get_ins_data: ct_describe failed ...");
break;
}
/*
printf ("\n Col:%s: Length:%d: \n", l_st_datafmt[i].name, l_st_datafmt[i].maxlength);
*/
memset (l_s_datatype, 0, sizeof (l_s_datatype));
memset (l_s_tmp, 0, sizeof (l_s_tmp));
memset (l_s_strnull, 0, sizeof (l_s_strnull));
l_i_retcode = f_gettypes (l_st_datafmt[i].datatype, l_s_datatype);
if (l_i_retcode < 0) {
f_errorlog ("fun_get_ins_data: malloc failed for coldata ...");
break;
}
/* For columns that need length and otherwise */
else if (l_i_retcode == 2 )
sprintf (l_s_tmp, " %s %s ", l_st_datafmt[i].name, l_s_datatype);
else if (l_i_retcode == 1 ) {
if (l_st_datafmt[i].scale > 0)
sprintf (l_s_tmp, " %s %s(%d, %d) " , l_st_datafmt[i].name, l_s_datatype, l_st_datafmt[i].maxlength, l_st_datafmt[i].scale);
else
sprintf (l_s_tmp, " %s %s(%d) " , l_st_datafmt[i].name, l_s_datatype, l_st_datafmt[i].maxlength);
}
/* Set sql for update if flag = UPDATE or UPDATE_ONLY */
if (p_upd_flag == 1) {
if ((i + 1) < l_i_num_cols)
sprintf (l_s_upd, " %s = t.%s, \n", l_st_datafmt[i].name, l_st_datafmt[i].name);
else
sprintf (l_s_upd, " %s = t.%s \n", l_st_datafmt[i].name, l_st_datafmt[i].name);
}
/* Build g_s_ins_string for all flags which would look as
** : col1, col2, col3, col4
*/
if ((i + 1) < l_i_num_cols)
sprintf (l_s_ins, "%s, ", l_st_datafmt[i].name);
else
sprintf (l_s_ins, "%s ", l_st_datafmt[i].name);
/* This is to add "" in the while inserting data, applies to char, varchar, text, datetime */
if ((l_st_datafmt[i].datatype == CS_CHAR_TYPE) || (l_st_datafmt[i].datatype == CS_VARCHAR_TYPE)
|| (l_st_datafmt[i].datatype == CS_TEXT_TYPE) || ( l_st_datafmt[i].datatype == CS_DATETIME_TYPE)
|| (l_st_datafmt[i].datatype == CS_DATETIME4_TYPE))
l_i_orig_datatype[i] = 1;
else
l_i_orig_datatype[i] = 0;
l_st_datafmt[i].maxlength = f_display_dlen(&l_st_datafmt[i]) + 1;
l_st_datafmt[i].datatype = CS_CHAR_TYPE;
l_st_datafmt[i].format = CS_FMT_NULLTERM;
/* Allocate memory for the column string */
l_st_coldata[i].value = (CS_CHAR *)malloc(l_st_datafmt[i].maxlength);
if (l_st_coldata[i].value == NULL) {
f_errorlog ("fun_get_ins_data: malloc failed for coldata ...");
break;
}
/* l_st_coldata[i].value, &l_st_coldata[i].valuelen,*/
/* Now bind. */
l_i_retcode = ct_bind(p_st_cmd, (i + 1), &l_st_datafmt[i],
l_st_coldata[i].value, &l_st_coldata[i].valuelen,
&l_st_coldata[i].indicator);
if (l_i_retcode != CS_SUCCEED) {
f_errorlog ("fun_get_ins_data: ct_bind failed for coldata ...");
break;
}
if (strlen (g_s_nullflag) > 0 && strcmp (g_s_nullflag, "NULL") == 0)
sprintf (l_s_strnull, " %s NULL , \n", l_s_tmp);
else
sprintf (l_s_strnull, "%s , \n", l_s_tmp);
strcat (l_s_sql, l_s_strnull);
strcat (g_s_update_sql, l_s_upd);
strcat (g_s_ins_string, l_s_ins);
}
strcat (l_s_sql, " )") ;
fprintf (stderr, "\nconnect server 6:%s \n\n", "test");
if (l_i_retcode != CS_SUCCEED) {
for (j = 0; j < i; j++)
free(l_st_coldata[j].value);
free(l_st_coldata);
free(l_st_datafmt);
return -1;
}
fprintf (stderr, "\nconnect server 7:%s \n\n", "test");
#ifdef PRINT
printf ("\n Create Table:\n%s \n", l_s_sql);
#endif
/* Create #tmp table on Dest server */
if ((l_i_retcode = f_exec_sql (p_st_dstcmd, l_s_sql)) != CS_SUCCEED)
return -1;
/* Fetch data from Source server and insert into #tmp table on Dest server */
while (((l_i_retcode = ct_fetch(p_st_cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
&l_i_rows_read)) == CS_SUCCEED) || (l_i_retcode == CS_ROW_FAIL))
{
l_i_row_count = l_i_row_count + l_i_rows_read;
if (l_i_retcode == CS_ROW_FAIL)
f_errorlog(stdout, "Error on row %d.\n", l_i_row_count);
/* For each row loop thro all columns and construct insert string */
strcpy (l_s_sql, "insert #tmp select ");
memset (l_s_tmp, 0, sizeof (l_s_tmp));
for (i = 0; i < l_i_num_cols; i++) {
/*
printf ("\nName: %s ColVal : %s Len: %d \n", l_st_datafmt[i].name, l_st_coldata[i].value, strlen (l_st_coldata[i].value));
*/
/* Fix for l_st_datafmt[i].maxlength == 1 done - for NULL values
** - 13 / Dec / 2000 Arun
if (strlen (l_st_coldata[i].value) == 0 || strlen (l_st_coldata[i].value) == 1) {
*/
if (strlen (l_st_coldata[i].value) == 0) {
strcpy (l_st_coldata[i].value, "NULL");
/* printf ("\n Null value"); */
}
if (l_i_orig_datatype[i] == 1) { /* Char datatype */
if ((strstr (l_st_coldata[i].value, QUOTE)) != NULL) {
p = (char *) strtok (l_st_coldata[i].value, QUOTE);
strcat (l_s_tmp, QUOTE);
strcat (l_s_tmp, p);
sprintf (l_s_tmp, "%s%s%s", l_s_tmp, QUOTE, QUOTE);
for ( ; p = (char *) strtok (NULL, QUOTE); )
strcat (l_s_tmp, p);
}
else {
strcat (l_s_tmp, QUOTE);
strcat (l_s_tmp, l_st_coldata[i].value);
}
strcat (l_s_tmp, QUOTE);
}
else
strcat (l_s_tmp, l_st_coldata[i].value);
if ((i + 1) < l_i_num_cols )
strcat (l_s_tmp, ", ");
}
strcat (l_s_sql, l_s_tmp);
/*
printf ("\n Insert string: %s\n", l_s_sql);
*/
/* Insert the data on DEST server and populate the #tmp table row by row */
if ((l_i_retcode = f_exec_sql (p_st_dstcmd, l_s_sql)) != CS_SUCCEED)
break;
}
fprintf (stderr, "\nconnect server 5:%s \n\n", "test");
/*Free allocated space */
for (i = 0; i < l_i_num_cols; i++)
free(l_st_coldata[i].value);
free(l_st_coldata);
free(l_st_datafmt);
if ( l_i_row_count == 0 ) {
f_errorlog ("No data found ");
return -1;
}
else
g_i_rows = l_i_row_count;
/* We're done processing rows. Let's check the final return value of ct_fetch() */
switch ((int)l_i_retcode) {
case CS_END_DATA:
/*
f_errorlog(g_fp_errfile, "fun_get_ins_data: All processing done.");
*/
break;
case CS_FAIL:
f_errorlog (g_fp_errfile, "fun_get_ins_data: Fetch failed.");
return -1;
default:
f_errorlog (g_fp_errfile, "fun_get_ins_data: Unexpected return value.");
return -1;
}
/* Create index on tmp table if specified at command line */
if (strlen (g_s_indexcols) > 0) {
sprintf (l_s_sql, "create index ind1 on #tmp (%s)", g_s_indexcols);
/*printf ("\n Index string: %s:\n", l_s_sql); */
if ((l_i_retcode = f_exec_sql (p_st_dstcmd, l_s_sql)) != CS_SUCCEED)
return -1;
}
return CS_SUCCEED;
}
/*
** This cleans up all the connections, command structures, file pointers that have been opened
*/
void fun_exit (i, p_st_dstcmd, p_st_srccmd)
int i;
CS_COMMAND *p_st_dstcmd;
CS_COMMAND *p_st_srccmd;
{
/* Deallocate everything */
ct_cmd_drop (p_st_dstcmd);
ct_cmd_drop (p_st_srccmd);
ct_close (g_st_dstconn, CS_UNUSED);
ct_con_drop (g_st_dstconn);
ct_close (g_st_srcconn, CS_UNUSED);
ct_con_drop (g_st_srcconn);
ct_exit (g_st_context, CS_UNUSED);
cs_ctx_drop (g_st_context);
fclose (g_fp_errfile);
exit (i);
}
void fun_process (argc, argv, arge)
int argc;
char **argv;
char **arge;
{
CS_COMMAND *l_st_srccmd;
CS_COMMAND *l_st_dstcmd;
char l_s_srcserver[MAXSTRING];
char l_s_srcuser[MAXSTRING];
char l_s_srcpass[MAXSTRING];
char l_s_sql[MAXSQL];
char l_s_parsql[MAXSQL];
char l_s_dstserver[MAXSTRING];
char l_s_dstuser[MAXSTRING];
char l_s_dstpass[MAXSTRING];
char l_s_table[MAXSTRING];
char l_s_flag[MAXSTRING];
char l_s_keys[MAXSQL];
char l_s_errlog[MAXSTRING];
char l_s_application[MAXSTRING];
char l_s_hostname[MAXSTRING];
char l_s_tmp[MAXSQL];
char l_s_finalsql[MAXSQL];
int l_i_return, i;
int l_i_updflag = 0;
char l_s_date[10], l_s_time[10];
/* Check the syntax */
if (argc != 15) {
fprintf (stderr, "\nUsage: repdata Query SourceServer SourceUser SourcePass DestServer DestUser DestPass \
DestTable ParameterQuery SqlFlag KeyColumns IndexColumns Logfile NullFlag\n");
exit (-1);
}
memset (l_s_srcserver, 0, sizeof(l_s_srcserver));
memset (l_s_srcuser, 0, sizeof(l_s_srcuser));
memset (l_s_srcpass, 0, sizeof(l_s_srcpass));
memset (l_s_sql, 0, sizeof(l_s_sql));
memset (l_s_dstserver, 0, sizeof(l_s_dstserver));
memset (l_s_dstuser, 0, sizeof(l_s_dstuser));
memset (l_s_dstpass, 0, sizeof(l_s_dstpass));
memset (l_s_table, 0, sizeof(l_s_table));
memset (l_s_flag, 0, sizeof(l_s_flag));
memset (g_s_update_sql, 0, sizeof(g_s_update_sql));
memset (g_s_ins_string, 0, sizeof(g_s_ins_string));
memset (l_s_date, 0, sizeof(l_s_date));
memset (l_s_time, 0, sizeof(l_s_time));
memset (g_s_indexcols, 0, sizeof(g_s_indexcols));
memset (g_s_nullflag, 0, sizeof(g_s_nullflag));
memset (l_s_tmp, 0, sizeof(l_s_tmp));
memset (l_s_finalsql, 0, sizeof(l_s_finalsql));
strcpy (l_s_application, "repdata");
strncpy (l_s_sql, argv[1], sizeof (l_s_sql) - 1);
strncpy (l_s_srcserver, argv[2], sizeof (l_s_srcserver) - 1);
strncpy (l_s_srcuser, argv[3], sizeof (l_s_srcuser) - 1);
strncpy (l_s_srcpass, argv[4], sizeof (l_s_srcpass) - 1);
strncpy (l_s_dstserver, argv[5], sizeof (l_s_dstserver) - 1);
strncpy (l_s_dstuser, argv[6], sizeof (l_s_dstuser) - 1);
strncpy (l_s_dstpass, argv[7], sizeof (l_s_dstpass) - 1);
strncpy (l_s_table, argv[8], sizeof (l_s_table) - 1);
strncpy (l_s_parsql, argv[9], sizeof (l_s_parsql) - 1);
strncpy (l_s_flag, argv[10], sizeof (l_s_flag) - 1);
strncpy (l_s_keys, argv[11], sizeof (l_s_keys) - 1);
strncpy (g_s_indexcols, argv[12], sizeof (g_s_indexcols) - 1);
strncpy (l_s_errlog, argv[13], sizeof (l_s_errlog) - 1);
strncpy (g_s_nullflag, argv[14], sizeof (g_s_nullflag) - 1);
if (strcmp (l_s_flag, "UPDATE") != 0 && strcmp (l_s_flag, "INSERT") != 0 \
&& strcmp (l_s_flag, "UPDATE_ONLY") != 0 \
&& strcmp (l_s_flag, "REPLACE") != 0) {
fprintf (stderr, "SqlFlag should be UPDATE or UPDATE_ONLY or INSERT or REPLACE \n");
exit (-1);
}
for(i=0; argv[i]; i++)
memset(argv[i], 0, sizeof(argv[i]));
if ((g_fp_errfile = fopen (l_s_errlog, "a+")) == NULL) {
fprintf (stderr, "\nCould not open error file:%s \n\n", l_s_errlog);
exit (-1);
}
if ((l_i_return = gethostname (l_s_hostname, 20)) == -1)
strcpy (l_s_hostname, "repdata_host");
fprintf (stderr, "\nrepdata_host:%s \n\n", l_s_hostname);
/* Get a context structure to use, initialise CT lib, install Server/Client error handlers */
if ((l_i_return = f_init (&g_st_context)) != CS_SUCCEED)
exit(-1);
fprintf (stderr, "\ninitialize CT lib:%s \n\n", l_s_hostname);
/* Connect to the 2 servers */
if ((l_i_return = f_connect (g_st_context, &g_st_dstconn, l_s_application, \
l_s_dstuser, l_s_dstpass, l_s_dstserver, l_s_hostname)) != CS_SUCCEED)
exit(-1);
fprintf (stderr, "\nconnect server 1:%s \n\n", l_s_hostname);
if ((l_i_return = f_connect (g_st_context, &g_st_srcconn, l_s_application, \
l_s_srcuser, l_s_srcpass, l_s_srcserver, l_s_hostname)) != CS_SUCCEED)
exit (-1);
fprintf (stderr, "\nconnect server 2:%s \n\n", l_s_hostname);
/* Allocate command structures to both the db connections */
if ((l_i_return = ct_cmd_alloc (g_st_srcconn, &l_st_srccmd)) == CS_FAIL) {
sprintf (l_s_tmp, "Could not allocate command structure for %s server", l_s_srcserver);
f_errorlog (l_s_tmp);
exit (-1);
}
fprintf (stderr, "\nconnect server 3:%s \n\n", l_s_hostname);
if ((l_i_return = ct_cmd_alloc (g_st_dstconn, &l_st_dstcmd)) == CS_FAIL) {
sprintf (l_s_tmp, "Could not allocate command structure for %s server", l_s_dstserver);
f_errorlog (l_s_tmp);
exit (-1);
}
fprintf (stderr, "\nconnect server 4:%s \n\n", l_s_hostname);
f_get_datetime (l_s_date, l_s_time);
sprintf (l_s_tmp, "Start of Job:%s:%s", l_s_date, l_s_time);
f_errorlog(l_s_tmp);
/* Execute parameter query on DEST server and stuff fetched value in Origininal Sql */
if (strlen (l_s_parsql) > 0)
if ((l_i_return = fun_parsql(l_st_dstcmd, l_s_sql, l_s_parsql, l_s_sql)) != CS_SUCCEED)
fun_exit (-1, l_st_dstcmd, l_st_srccmd);
fprintf (stderr, "\nExecute parameter query on DEST:%s \n\n", l_s_hostname);
strcpy (l_s_tmp, "BEGIN TRAN");
if (strcmp (l_s_flag, "UPDATE") == 0 || strcmp (l_s_flag, "UPDATE_ONLY") == 0) {
if (strlen (l_s_keys) == 0) {
f_errorlog ("Specify update keys for UPDATE and UPDATE_ONLY flags");
fun_exit (-1, l_st_dstcmd, l_st_srccmd);
}
sprintf (g_s_update_sql, " %s\n update %s\n set ", l_s_tmp, l_s_table);
l_i_updflag = 1;
}
/* Execute the Original Sql on Source server */
if ((l_i_return = fun_sourcesql(l_st_srccmd, l_st_dstcmd, l_s_sql, l_i_updflag )) != CS_SUCCEED)
fun_exit (-1, l_st_dstcmd, l_st_srccmd);
if (strcmp (l_s_flag, "REPLACE") == 0)
sprintf (l_s_tmp, "%s \ndelete %s \ninsert into %s (%s) \nselect %s from #tmp", \
l_s_tmp, l_s_table, l_s_table, g_s_ins_string, g_s_ins_string);
else if (strcmp (l_s_flag, "INSERT") == 0)
sprintf (l_s_tmp, "%s \ninsert into %s (%s) \nselect %s from #tmp", \
l_s_tmp, l_s_table, g_s_ins_string, g_s_ins_string);
else if (strcmp (l_s_flag, "UPDATE") == 0) {
sprintf (l_s_tmp, " %s \n%s from #tmp t , %s where %s",
l_s_tmp, g_s_update_sql, l_s_table, l_s_keys);
sprintf (l_s_tmp, "%s\n insert into %s (%s) \n select %s from #tmp t\n", l_s_tmp, l_s_table, g_s_ins_string, g_s_ins_string);
sprintf (l_s_tmp, "%s where not exists (select * from %s where %s) \n", l_s_tmp, l_s_table, l_s_keys);
}
else if (strcmp (l_s_flag, "UPDATE_ONLY") == 0) {
sprintf (l_s_tmp, " %s \n%s from #tmp t , %s where %s",
l_s_tmp, g_s_update_sql, l_s_table, l_s_keys);
}
sprintf (l_s_finalsql, "%s \nCOMMIT TRAN \n", l_s_tmp);
#ifdef PRINT
printf ("\n FINAL:\n%s \n", l_s_finalsql);
#endif
/* Copy the data from #tmp table to DEST table */
if ((l_i_return = f_exec_sql(l_st_dstcmd, l_s_finalsql)) != CS_SUCCEED)
fun_exit (-1, l_st_dstcmd, l_st_srccmd);
f_get_datetime (l_s_date, l_s_time);
sprintf (l_s_tmp, "SQL: %s ==> ToTable: %s \nFetched Rows: %d\n\nEnd of job:%s:%s\n==========================", l_s_sql, l_s_table, g_i_rows, l_s_date, l_s_time);
f_errorlog (l_s_tmp);
fun_exit (1, l_st_dstcmd, l_st_srccmd);
}
main (argc, argv, arge)
int argc;
char **argv;
char **arge;
{
f_installsignalhandler();
fun_process(argc, argv, arge);
}
------------------------------------------------------------------------
|