Skip to content

Commit

Permalink
Merge branch 'BABEL_3_X_DEV' into BABEL-4590
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohit Bhagat committed Dec 29, 2023
2 parents f5709f9 + fb1b4c5 commit 19f6be3
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 39 deletions.
19 changes: 19 additions & 0 deletions contrib/babelfishpg_tds/src/backend/tds/tds_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,25 @@ pe_authenticate(Port *port, const char **username)

appendStringInfo(&logmsg, _(" Tds Version=0x%X."), GetClientTDSVersion());

#ifdef ENABLE_GSS
if (port->gss)
{
const char *princ = be_gssapi_get_princ(port);

if (princ)
appendStringInfo(&logmsg,
_(" GSS (authenticated=%s, encrypted=%s, principal=%s)"),
be_gssapi_get_auth(port) ? _("yes") : _("no"),
be_gssapi_get_enc(port) ? _("yes") : _("no"),
princ);
else
appendStringInfo(&logmsg,
_(" GSS (authenticated=%s, encrypted=%s)"),
be_gssapi_get_auth(port) ? _("yes") : _("no"),
be_gssapi_get_enc(port) ? _("yes") : _("no"));
}
#endif

ereport(LOG, errmsg_internal("%s", logmsg.data));
pfree(logmsg.data);
}
Expand Down
19 changes: 19 additions & 0 deletions contrib/babelfishpg_tds/src/backend/tds/tdslogin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@ CheckGSSAuth(Port *port)
gss_buffer_desc gbuf;
MemoryContext oldContext;
char *at_pos = NULL;
char *princ;

if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0)
{
Expand Down Expand Up @@ -1583,6 +1584,24 @@ CheckGSSAuth(Port *port)
_("retrieving GSS user name failed"),
maj_stat, min_stat);

/*
* gbuf.value might not be null-terminated, so turn it into a regular
* null-terminated string.
*/
princ = palloc(gbuf.length + 1);
memcpy(princ, gbuf.value, gbuf.length);
princ[gbuf.length] = '\0';

/*
* Copy the original name of the authenticated principal into our backend
* memory for display later.
*
* This is also our authenticated identity. Set it now, rather than
* waiting for the usermap check below, because authentication has already
* succeeded and we want the log file to reflect that.
*/
port->gss->princ = MemoryContextStrdup(TopMemoryContext, princ);

/*
* XXX: In PG there are options to match realm names or perform ident
* mappings. We're not going to do those checks now. If required, we can
Expand Down
7 changes: 7 additions & 0 deletions contrib/babelfishpg_tds/test/t/002_tdskerberos.pl
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,13 @@ sub test_query
my @connstr1 = $tsql_node->tsql_connstr('master');
$tsql_node->connect_ok('Kerberos auth test', (connstr => \@connstr1));

$tsql_node->connect_ok('pg_stat_gssapi and connection log test',
(connstr => \@connstr1,
sql => "SELECT gss_authenticated, principal from pg_stat_gssapi where pid = pg_backend_pid();",
expected_stdout => qr/1.*test1\@$realm/,
log_like => [qr/connection authorized: user=test1\@$realm, application=SQLCMD, Tds Version=0x\d\d\d\d\d\d\d\d. GSS \(authenticated=yes, encrypted=no, principal=test1\@$realm\)/]));


# Reset pg_hba.conf and mark every connection to use password based auth
# But we should be able to use kerberos auth through TDS endpoint irrespective
# of pg_hba.conf file
Expand Down
1 change: 1 addition & 0 deletions contrib/babelfishpg_tsql/src/fts_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ extern int fts_yylex(void);
extern void fts_yyerror(char **result, const char *message) pg_attribute_noreturn();
extern void fts_scanner_init(const char *str);
extern void fts_scanner_finish(void);
extern bool isNonEnglishString(const char *str);

/* in fts_parser.y */
extern int fts_yyparse(char **result);
Expand Down
59 changes: 34 additions & 25 deletions contrib/babelfishpg_tsql/src/fts_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ static int scanbuflen;

static char* translate_simple_term(const char* s);
static char *trim(char *s, bool insideQuotes);
static bool containsSpecialCharacters(char s);

%}

%token WORD_TOKEN WS_TOKEN TEXT_TOKEN PREFIX_TERM_TOKEN GENERATION_TERM_TOKEN AND_TOKEN AND_NOT_TOKEN OR_TOKEN INFLECTIONAL_TOKEN THESAURUS_TOKEN FORMSOF_TOKEN O_PAREN_TOKEN C_PAREN_TOKEN COMMA_TOKEN
%token WORD_TOKEN WS_TOKEN TEXT_TOKEN PREFIX_TERM_TOKEN GENERATION_TERM_TOKEN AND_TOKEN NOT_TOKEN AND_NOT_TOKEN OR_TOKEN INFLECTIONAL_TOKEN THESAURUS_TOKEN FORMSOF_TOKEN O_PAREN_TOKEN C_PAREN_TOKEN COMMA_TOKEN SPECIAL_CHAR_TOKEN NON_ENGLISH_TOKEN
%left OR_TOKEN
%left AND_TOKEN
%left AND_NOT_TOKEN
Expand Down Expand Up @@ -86,10 +87,10 @@ generation_term:

generation_type:
INFLECTIONAL_TOKEN {
$$ = $1;
fts_yyerror(NULL, "Generation term is not currently supported in Babelfish");
}
| THESAURUS_TOKEN {
$$ = $1;
fts_yyerror(NULL, "Generation term is not currently supported in Babelfish");
}
;

Expand Down Expand Up @@ -138,27 +139,35 @@ char* translate_simple_term(const char* inputStr) {
inputLength = strlen(trimmedInputStr);

initStringInfo(&output);
appendStringInfoString(&output, "");

// Initialize pointers for input and output
inputPtr = trimmedInputStr;

while (*inputPtr != '\0') {
if (*inputPtr == ' ') {
for (inputPtr = trimmedInputStr; *inputPtr != '\0'; inputPtr++) {
if (isspace((unsigned char)*inputPtr)) {
// Replace space with "<->"
while (*(inputPtr + 1) == ' ') {
while (isspace((unsigned char)*(inputPtr + 1))) {
// Handle multiples spaces between words and skip over additional spaces
inputPtr++;
}
appendStringInfoString(&output, "<->");
} else if (*inputPtr != '-' && containsSpecialCharacters((unsigned char)*inputPtr)) { // Handle special characters and other languages
pfree(trimmedInputStr);
yyerror(NULL, "Full-text search conditions with special characters or languages other than English are not currently supported in Babelfish");
} else {
// Copy the character
appendStringInfoChar(&output, *inputPtr);
}
inputPtr++;
}
pfree(trimmedInputStr);
return output.data;
} else {
// Initialize pointers for input and output
for (inputPtr = trimmedInputStr; *inputPtr != '\0'; inputPtr++) {
if (*inputPtr != '-' && containsSpecialCharacters((unsigned char)*inputPtr)) { // Handle special characters and other languages
pfree(trimmedInputStr);
yyerror(NULL, "Full-text search conditions with special characters or languages other than English are not currently supported in Babelfish");
}
}
// It's a single word, so no transformation needed
return trimmedInputStr;
}
Expand All @@ -173,7 +182,6 @@ static char *trim(char *s, bool insideQuotes) {
size_t start;
size_t end;
size_t newLength;
bool inQuotes;

/*
* Empty string, nothing to trim
Expand All @@ -184,26 +192,22 @@ static char *trim(char *s, bool insideQuotes) {
return s;
}

inQuotes = false;
start = 0;
end = length - 1;

for (size_t i = 0; i < length; i++) {
if (s[i] == '"') {
inQuotes = !inQuotes;
}
if(insideQuotes) {
start++;
end--;
}

if (!inQuotes || insideQuotes) {
// Trim leading spaces
while (start < length && isspace(s[start])) {
start++;
}
// Trim leading spaces
while (start < length && isspace(s[start])) {
start++;
}

// Trim trailing spaces
while (end > start && isspace(s[end])) {
end--;
}
}
// Trim trailing spaces
while (end > start && isspace(s[end])) {
end--;
}

// Calculate the new length
Expand All @@ -218,4 +222,9 @@ static char *trim(char *s, bool insideQuotes) {
return s;
}

static bool containsSpecialCharacters(char str) {
// Ignore Non-breaking space character
return str != '\302' && str != -62 && str != '\240' && str != -96 && !isalnum(str) && !isspace(str);
}

# include "fts_scan.c"
39 changes: 31 additions & 8 deletions contrib/babelfishpg_tsql/src/fts_scan.l
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ static YY_BUFFER_STATE scanbufhandle;

%%

"AND" { yylval = "AND"; yyerror(NULL, "Boolean operator is not currently supported in Babelfish"); return AND_TOKEN; }
"AND NOT" { yylval = "AND NOT"; yyerror(NULL, "Boolean operator is not currently supported in Babelfish"); return AND_NOT_TOKEN; }
"OR" { yylval = "OR"; yyerror(NULL, "Boolean operator is not currently supported in Babelfish"); return OR_TOKEN; }
"AND" { yylval = "AND"; yyerror(NULL, "Full-text search conditions with boolean operators are not currently supported in Babelfish"); return AND_TOKEN; }
"AND NOT" { yylval = "AND NOT"; yyerror(NULL, "Full-text search conditions with boolean operators are not currently supported in Babelfish"); return AND_NOT_TOKEN; }
"OR" { yylval = "OR"; yyerror(NULL, "Full-text search conditions with boolean operators are not currently supported in Babelfish"); return OR_TOKEN; }
"NOT" { yylval = "NOT"; yyerror(NULL, "Full-text search conditions with boolean operators are not currently supported in Babelfish"); return NOT_TOKEN; }
"INFLECTIONAL" { yylval = "INFLECTIONAL"; return INFLECTIONAL_TOKEN; }
"THESAURUS" { yylval = "THESAURUS"; return THESAURUS_TOKEN; }
"FORMSOF" { yylval = "FORMSOF"; return FORMSOF_TOKEN; }
Expand All @@ -32,13 +33,13 @@ static YY_BUFFER_STATE scanbufhandle;
"," { yylval = ","; return COMMA_TOKEN; }
[ \t\r\n]+ { yylval = " "; return WS_TOKEN; }

\"[^"]+\*\" { if (yytext[strlen(yytext)-2] == ' ') { yyerror(NULL, "Syntax error, space is not allowed before *"); } yylval = yytext; return PREFIX_TERM_TOKEN; } // Handle prefix terms
[a-zA-Z0-9]+ { yylval = yytext; return WORD_TOKEN; } // Handle individual words
\"[^"*]*\" { yylval = yytext; return TEXT_TOKEN; } // Handle double-quoted phrases

FORMSOF\s*\(\s*(INFLECTIONAL|THESAURUS)\s*,\s*((\w+)|(\"[\w\s]+\"))(\s*,\s*((\w+)|(\"[\w\s]+\")))*\s*\) { yylval = yytext; return GENERATION_TERM_TOKEN; } // Handle FORMSOF generation term
FORMSOF\s*\(\s*(INFLECTIONAL|THESAURUS)\s*,\s*((\w+)|(\"[\w\s]+\"))(\s*,\s*((\w+)|(\"[\w\s]+\")))*\s*\) { yylval = yytext; yyerror(NULL, "Generation term is not currently supported in Babelfish"); yylval = yytext; return GENERATION_TERM_TOKEN; } // Handle FORMSOF generation term
\"[^"]+\*\" { if (yytext[strlen(yytext)-2] == ' ') { yyerror(NULL, "Syntax error, space is not allowed before *"); } yylval = yytext; return PREFIX_TERM_TOKEN; } // Handle prefix terms
\"[^"]*\" { yylval = yytext; return TEXT_TOKEN; } // Handle double-quoted phrases
[a-zA-Z0-9]+ { yylval = yytext; return WORD_TOKEN; } // Handle individual words

. { return yytext[0]; } // Other characters are returned as-is
. { return yytext[0]; } // Other characters are returned as-is

%%

Expand Down Expand Up @@ -72,6 +73,11 @@ fts_scanner_init(const char *str)
yyerror(NULL, "Null or empty full-text predicate.");
}

// Check for Non-English Language, if true, throw unsupported error
if(isNonEnglishString(str)) {
yyerror(NULL, "Full-text search conditions with special characters or languages other than English are not currently supported in Babelfish");
}

/*
* Make a scan buffer with special termination needed by flex.
*/
Expand All @@ -93,3 +99,20 @@ fts_scanner_finish(void)
yy_delete_buffer(scanbufhandle);
pfree(scanbuf);
}

/*
* Util function to check if the string is of Non-English language
*/
bool
isNonEnglishString(const char *str) {
for (const char *p = str; *p; p++) {
// Ignore non-breaking space character
if ((*p == '\302' && *p == -62 ) || (*p == '\240' && *p == -96)) {
continue;
}
if (*p < 0 || *p > 127) {
return true;
}
}
return false;
}
Loading

0 comments on commit 19f6be3

Please sign in to comment.