Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
	LOGINREC *login;
	DBPROCESS *dbproc;
	int i;
	DBINT rowint;
	DBCHAR rowchar[2];
	DBCHAR rowdate[32];

	DBINT rowtype;
	DBINT computeint;
	DBCHAR computedate[32];

	set_malloc_options();
	read_login_info(argc, argv);

	fprintf(stdout, "Starting %s\n", argv[0]);

	/* Fortify_EnterScope(); */
	dbinit();

	dberrhandle(syb_err_handler);
	dbmsghandle(syb_msg_handler);

	fprintf(stdout, "About to logon\n");

	login = dblogin();
	DBSETLPWD(login, PASSWORD);
	DBSETLUSER(login, USER);
	DBSETLAPP(login, "t0023");

	fprintf(stdout, "About to open\n");

	dbproc = dbopen(login, SERVER);
	if (strlen(DATABASE))
		dbuse(dbproc, DATABASE);
	dbloginfree(login);

    if (dbproc != NULL) {
        TDSSOCKET *tds = dbproc->tds_socket;
        if (TDS_IS_MSSQL(tds)
            &&  tds->conn->product_version >= TDS_MS_VER(11, 0, 0)) {
            fputs("Skipping COMPUTE tests with MS SQL 2012+.\n", stderr);
            return 77;
        }
    }

	fprintf(stdout, "creating table\n");
	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}

	fprintf(stdout, "insert\n");

	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}
	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}
	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}
	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}
	sql_cmd(dbproc);
	dbsqlexec(dbproc);
	while (dbresults(dbproc) == SUCCEED) {
		/* nop */
	}

	fprintf(stdout, "select\n");
	sql_cmd(dbproc);
	dbsqlexec(dbproc);

	if (dbresults(dbproc) != SUCCEED) {
		failed = 1;
		fprintf(stdout, "Was expecting a result set.\n");
		exit(1);
	}

	for (i = 1; i <= dbnumcols(dbproc); i++)
		printf("col %d is %s\n", i, dbcolname(dbproc, i));

	fprintf(stdout, "binding row columns\n");
	if (SUCCEED != dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & rowint)) {
		failed = 1;
		fprintf(stderr, "Had problem with bind col1\n");
		abort();
	}
	if (SUCCEED != dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) rowchar)) {
		failed = 1;
		fprintf(stderr, "Had problem with bind col2\n");
		abort();
	}
	if (SUCCEED != dbbind(dbproc, 3, STRINGBIND, 0, (BYTE *) rowdate)) {
		failed = 1;
		fprintf(stderr, "Had problem with bind col3\n");
		abort();
	}

	fprintf(stdout, "testing compute clause 1\n");

	if (dbnumalts(dbproc, 1) != 1) {
		failed = 1;
		fprintf(stderr, "Had problem with dbnumalts 1\n");
		abort();
	}

	if (dbalttype(dbproc, 1, 1) != SYBINT4) {
		failed = 1;
		fprintf(stderr, "Had problem with dbalttype 1, 1\n");
		abort();
	}

	if (dbaltcolid(dbproc, 1, 1) != 1) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltcolid 1, 1\n");
		abort();
	}

	if (dbaltop(dbproc, 1, 1) != SYBAOPSUM) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltop 1, 1\n");
		abort();
	}

	if (SUCCEED != dbaltbind(dbproc, 1, 1, INTBIND, 0, (BYTE *) & computeint)) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltbind 1, 1\n");
		abort();
	}


	fprintf(stdout, "testing compute clause 2\n");

	if (dbnumalts(dbproc, 2) != 1) {
		failed = 1;
		fprintf(stderr, "Had problem with dbnumalts 2\n");
		abort();
	}

	if (dbalttype(dbproc, 2, 1) != SYBDATETIME) {
		failed = 1;
		fprintf(stderr, "Had problem with dbalttype 2, 1\n");
		abort();
	}

	if (dbaltcolid(dbproc, 2, 1) != 3) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltcolid 2, 1\n");
		abort();
	}

	if (dbaltop(dbproc, 2, 1) != SYBAOPMAX) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltop 2, 1\n");
		abort();
	}

	if (SUCCEED != dbaltbind(dbproc, 2, 1, STRINGBIND, -1, (BYTE *) computedate)) {
		failed = 1;
		fprintf(stderr, "Had problem with dbaltbind 2, 1\n");
		abort();
	}

	while ((rowtype = dbnextrow(dbproc)) != NO_MORE_ROWS) {

		if (rowtype == REG_ROW) {
			printf("gotten a regular row\n");
		}

		if (rowtype == 1) {
			printf("gotten a compute row for clause 1\n");
			printf("value of sum(col1) = %d\n", computeint);
		}

		if (rowtype == 2) {
			printf("gotten a compute row for clause 2\n");
			printf("value of max(col3) = %s\n", computedate);

		}
	}

	dbexit();

	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
	return failed ? 1 : 0;
}
Ejemplo n.º 2
0
/*
 * Function transformation (from ODBC to Sybase)
 * String functions
 * ASCII(string) -> ASCII(string)
 * BIT_LENGTH(string) -> 8*OCTET_LENGTH(string)
 * CHAR_LENGTH(string_exp) -> CHAR_LENGTH(string_exp)
 * CHARACTER_LENGTH(string_exp) -> CHAR_LENGTH(string_exp)
 * CONCAT(string_exp1, string_exp2) -> string_exp1 + string_exp2
 * DIFFERENCE(string_exp1, string_exp2) -> DIFFERENCE(string_exp1, string_exp2)
 * INSERT(string_exp1, start, length, string_exp2) -> STUFF(sameparams)
 * LCASE(string_exp) -> LOWER(string)
 * LEFT(string_exp, count) -> SUBSTRING(string, 1, count)
 * LENGTH(string_exp) -> CHAR_LENGTH(RTRIM(string_exp))
 * LOCATE(string, string [,start]) -> CHARINDEX(string, string)
 * (SQLGetInfo should return third parameter not possible)
 * LTRIM(String) -> LTRIM(String)
 * OCTET_LENGTH(string_exp) -> OCTET_LENGTH(string_exp)
 * POSITION(character_exp IN character_exp) ???
 * REPEAT(string_exp, count) -> REPLICATE(same)
 * REPLACE(string_exp1, string_exp2, string_exp3) -> ??
 * RIGHT(string_exp, count) -> RIGHT(string_exp, count)
 * RTRIM(string_exp) -> RTRIM(string_exp)
 * SOUNDEX(string_exp) -> SOUNDEX(string_exp)
 * SPACE(count) (ODBC 2.0) -> SPACE(count) (ODBC 2.0)
 * SUBSTRING(string_exp, start, length) -> SUBSTRING(string_exp, start, length)
 * UCASE(string_exp) -> UPPER(string)
 *
 * Numeric
 * Nearly all function use same parameters, except:
 * ATAN2 -> ATN2
 * TRUNCATE -> ??
 */
static SQLRETURN
to_native(struct _hdbc *dbc, struct _hstmt *stmt, DSTR *str)
{
	char *d, *s;
	int nest_syntax = 0;
	char *buf = tds_dstr_buf(str);

	/* list of bit, used as stack, is call ? FIXME limites size... */
	unsigned long is_calls = 0;
	int server_scalar;

	assert(dbc);

	server_scalar = TDS_IS_MSSQL(dbc->tds_socket) && dbc->tds_socket->conn->product_version >= TDS_MS_VER(7, 0, 0);

	/*
	 * we can do it because result string will be
	 * not bigger than source string
	 */
	d = s = buf;
	while (*s) {
		if (*s == '-' || *s == '/') {
			size_t len_comment = tds_skip_comment(s) - s;

			memmove(d, s, len_comment);
			s += len_comment;
			d += len_comment;
			continue;
		}

		/* TODO: test syntax like "select 1 as [pi]]p)p{?=call]]]]o], 2" on mssql7+ */
		if (*s == '"' || *s == '\'' || *s == '[') {
			size_t len_quote = tds_skip_quoted(s) - s;

			memmove(d, s, len_quote);
			s += len_quote;
			d += len_quote;
			continue;
		}

		if (*s == '{') {
			char *pcall;

			while (TDS_ISSPACE(*++s))
				continue;
			pcall = s;
			/* FIXME if nest_syntax > 0 problems */
			if (server_scalar && strncasecmp(pcall, "fn ", 3) == 0) {
				*d++ = '{';
				continue;
			}
			if (*pcall == '?') {
				/* skip spaces after ? */
				while (TDS_ISSPACE(*++pcall))
					continue;
				if (*pcall == '=') {
					while (TDS_ISSPACE(*++pcall))
						continue;
				} else {
					/* avoid {?call ... syntax */
					pcall = s;
				}
			}
			if (strncasecmp(pcall, "call ", 5) != 0)
				pcall = NULL;

			if (stmt)
				stmt->prepared_query_is_rpc = 1;
			++nest_syntax;
			is_calls <<= 1;
			if (!pcall) {
				/* assume syntax in the form {type ...} */
				while (TDS_ISALPHA(*s))
					++s;
				while (TDS_ISSPACE(*s))
					++s;
			} else {
				if (*s == '?' && stmt)
					stmt->prepared_query_is_func = 1;
				memcpy(d, "exec ", 5);
				d += 5;
				s = pcall + 5;
				is_calls |= 1;
			}
		} else if (nest_syntax > 0) {
			/* do not copy close syntax */
			if (*s == '}') {
				--nest_syntax;
				is_calls >>= 1;
				++s;
				continue;
				/* convert parenthesis in call to spaces */
			} else if ((is_calls & 1) && (*s == '(' || *s == ')')) {
				*d++ = ' ';
				s++;
			} else {
				*d++ = *s++;
			}
		} else {