Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix MSVC2015 build & mssql instance name support & fix fails on IMPORT FOREIGN SCHEMA... #162

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
/freetds
/.vs
/*.vcx*
/*.sln
/x64
/*.user
/*.opendb
/*.db
1 change: 1 addition & 0 deletions include/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef struct TdsFdwOption
typedef struct TdsFdwOptionSet
{
char *servername;
char *instance_name;
char *language;
char *character_set;
int port;
Expand Down
6 changes: 4 additions & 2 deletions include/tds_fdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@

#include "options.h"


#if PG_VERSION_NUM >= 90500
#define IMPORT_API
#define IGNORE_DEFAULT_COLUMN_VALUES //this flag disable default col values for CREATE FOREIGN TABLE syntax due to the use of built-in functions for the default value. (fails on IMPORT FOREIGN SCHEMA...)
#else
#undef IMPORT_API
#endif /* PG_VERSION_NUM */
Expand Down Expand Up @@ -127,8 +129,8 @@ typedef struct

/* functions called via SQL */

extern Datum tds_fdw_handler(PG_FUNCTION_ARGS);
extern Datum tds_fdw_validator(PG_FUNCTION_ARGS);
extern PGDLLEXPORT Datum tds_fdw_handler(PG_FUNCTION_ARGS);
extern PGDLLEXPORT Datum tds_fdw_validator(PG_FUNCTION_ARGS);

/* FDW callback routines */

Expand Down
22 changes: 15 additions & 7 deletions src/deparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,6 @@ deparseSelectSql(StringInfo buf,
/*
* Construct FROM clause
*/
appendStringInfoString(buf, " FROM ");
deparseRelation(buf, rel);

heap_close(rel, NoLock);
Expand Down Expand Up @@ -1244,12 +1243,21 @@ deparseRelation(StringInfo buf, Relation rel)
if (relname == NULL)
relname = RelationGetRelationName(rel);*/

if (nspname == NULL)
appendStringInfo(buf, "%s",
relname);
else
appendStringInfo(buf, "%s.%s",
tds_quote_identifier(nspname), tds_quote_identifier(relname));

if (relname != NULL) {
appendStringInfoString(buf, " FROM ");
if (nspname == NULL)
appendStringInfo(buf, "%s",
relname);
else
appendStringInfo(buf, "%s.%s",
tds_quote_identifier(nspname), tds_quote_identifier(relname));
}
else {
// from clause miss. query like this: "select current_date() as curdt"
}


}

/*
Expand Down
35 changes: 34 additions & 1 deletion src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void tdsOptionSetInit(TdsFdwOptionSet* option_set);
static struct TdsFdwOption valid_options[] =
{
{ "servername", ForeignServerRelationId },
{ "instance_name", ForeignServerRelationId },
{ "language", ForeignServerRelationId },
{ "character_set", ForeignServerRelationId },
{ "port", ForeignServerRelationId },
Expand Down Expand Up @@ -94,7 +95,7 @@ static const int DEFAULT_MATCH_COLUMN_NAMES = 1;

/* by default we use remote estimates */

static const int DEFAULT_USE_REMOTE_ESTIMATE = 1;
static const int DEFAULT_USE_REMOTE_ESTIMATE = 0; //! https://www.postgresql.org/docs/9.3/static/postgres-fdw.html The default is false. otherwise, it triggers a triple same query execution

/* by default we use remote estimates */

Expand Down Expand Up @@ -260,6 +261,17 @@ void tdsGetForeignServerOptions(List *options_list, TdsFdwOptionSet *option_set)

option_set->servername = defGetString(def);
}
else if (strcmp(def->defname, "instance_name") == 0)
{
if (option_set->instance_name)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("Redundant option: instance_name (%s)", defGetString(def))
));

option_set->instance_name = defGetString(def);
}


else if (strcmp(def->defname, "language") == 0)
{
Expand Down Expand Up @@ -737,6 +749,26 @@ void tdsSetDefaultOptions(TdsFdwOptionSet *option_set)
));
#endif
}

if (!option_set->instance_name)
{
char * inst_name = "";
if ((option_set->instance_name = palloc((strlen(inst_name) + 1) * sizeof(char))) == NULL)
{
ereport(ERROR,
(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
errmsg("Failed to allocate memory for instance_name")
));
}

sprintf(option_set->instance_name, "%s", inst_name);

#ifdef DEBUG
ereport(NOTICE,
(errmsg("Set instance_name to default: %s", option_set->instance_name)
));
#endif
}

if (!option_set->row_estimate_method)
{
Expand Down Expand Up @@ -917,6 +949,7 @@ void tdsOptionSetInit(TdsFdwOptionSet* option_set)
#endif

option_set->servername = NULL;
option_set->instance_name = NULL;
option_set->language = NULL;
option_set->character_set = NULL;
option_set->port = 0;
Expand Down
33 changes: 25 additions & 8 deletions src/tds_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include <sybfront.h>
#include <sybdb.h>


/* #define DEBUG */

PG_MODULE_MAGIC;
Expand All @@ -76,6 +77,8 @@ PG_MODULE_MAGIC;
#include "options.h"
#include "deparse.h"



/* run on module load */

extern PGDLLEXPORT void _PG_init(void);
Expand Down Expand Up @@ -517,11 +520,15 @@ int tdsSetupConnection(TdsFdwOptionSet* option_set, LOGINREC *login, DBPROCESS *

conn_string = palloc((strlen(option_set->servername) + 10) * sizeof(char));

if (option_set->port)
{
sprintf(conn_string, "%s:%i", option_set->servername, option_set->port);
}

if (strlen(option_set->instance_name))
{
sprintf(conn_string, "%s\\%s", option_set->servername, option_set->instance_name);
}
else if (option_set->port)
{
sprintf(conn_string, "%s:%i", option_set->servername, option_set->port);
}

else
{
sprintf(conn_string, "%s", option_set->servername);
Expand Down Expand Up @@ -1407,7 +1414,8 @@ void tdsGetColumnMetadata(ForeignScanState *node, TdsFdwOptionSet *option_set)
(errmsg("tds_fdw: Comparing retrieved column name to the following local column name: %s", local_name)
));

if (strncmp(local_name, column->name, NAMEDATALEN) == 0)
//! \PPV local_name always in lowcase. But column->name's register defined in sql server. so you should ignore case
if (strnicmp(local_name, column->name, NAMEDATALEN) == 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this is crashing tds_fdw on loading: https://jenkins.juliogonzalez.es/job/tds_fdw-build-pr/44/DISTRO=ubuntu14.04,PG_VER=9.2,label=docker/console

Could it be that strnicmp is not part of the standard library and MS stuff only?

{
ereport(DEBUG3,
(errmsg("tds_fdw: It matches!")
Expand Down Expand Up @@ -1440,7 +1448,9 @@ void tdsGetColumnMetadata(ForeignScanState *node, TdsFdwOptionSet *option_set)
));

column->local_index = ncol;
column->attr_oid = festate->attinmeta->tupdesc->attrs[ncol]->atttypid;
//!\PPV fix crash on index miss!
if(ncol < festate->attinmeta->tupdesc->natts)
column->attr_oid = festate->attinmeta->tupdesc->attrs[ncol]->atttypid;
}

ereport(DEBUG3,
Expand Down Expand Up @@ -3228,9 +3238,16 @@ tdsImportSqlServerSchema(ImportForeignSchemaStmt *stmt, DBPROCESS *dbproc,
deparseStringLiteral(&buf, column_name);
appendStringInfoChar(&buf, ')');

/* Add DEFAULT if needed */

#ifndef IGNORE_DEFAULT_COLUMN_VALUES
/* Add DEFAULT if needed */
if (import_default && column_default[0] != '\0')
appendStringInfo(&buf, " DEFAULT %s", column_default);
#endif /* PG_VERSION_NUM */





/* Add NOT NULL if needed */
if (import_not_null && strcmp(is_nullable, "NO") == 0)
Expand Down