Skip to content

Commit 70c3a56

Browse files
author
anju15bharti
committed
Store original name in reloption for temp table and index on it
1 parent 8872ab4 commit 70c3a56

22 files changed

Lines changed: 2666 additions & 231 deletions

contrib/babelfishpg_tsql/runtime/functions.c

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,14 @@
5151
#include "utils/float.h"
5252
#include "utils/xid8.h"
5353
#include "utils/xml.h"
54+
#include "catalog/pg_class_d.h"
5455
#include <math.h>
5556

57+
extern const char *ATTOPTION_BBF_ORIGINAL_TABLE_NAME;
58+
extern char *get_value_by_name_from_array(ArrayType *array, const char *name);
59+
60+
static char *get_orig_temp_table_name(Oid relid);
61+
5662
#include "../src/babelfish_version.h"
5763
#include "../src/datatype_info.h"
5864
#include "../src/pltsql.h"
@@ -1319,7 +1325,19 @@ get_enr_list(PG_FUNCTION_ARGS)
13191325
MemSet(nulls, 0, sizeof(nulls));
13201326

13211327
values[0] = ((EphemeralNamedRelationMetadata) lfirst(lc))->reliddesc;
1322-
values[1] = CStringGetTextDatum(((EphemeralNamedRelationMetadata) lfirst(lc))->name);
1328+
{
1329+
EphemeralNamedRelationMetadata md = (EphemeralNamedRelationMetadata) lfirst(lc);
1330+
const char *name = md->name;
1331+
1332+
/* Use original untruncated name from reloptions if available */
1333+
if (md->enrtype == ENR_TSQL_TEMP)
1334+
{
1335+
char *orig = get_orig_temp_table_name(md->reliddesc);
1336+
if (orig)
1337+
name = orig;
1338+
}
1339+
values[1] = CStringGetTextDatum(name);
1340+
}
13231341

13241342
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
13251343
}
@@ -2798,6 +2816,33 @@ object_id(PG_FUNCTION_ARGS)
27982816
* if there is no such object in specified database, if database id is not provided it will lookup in current database
27992817
* if user don't have right permission
28002818
*/
2819+
/*
2820+
* get_orig_temp_table_name - Get original untruncated name from reloptions.
2821+
* Returns palloc'd string or NULL if not found.
2822+
*/
2823+
static char *
2824+
get_orig_temp_table_name(Oid relid)
2825+
{
2826+
HeapTuple tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
2827+
char *orig = NULL;
2828+
2829+
if (HeapTupleIsValid(tuple))
2830+
{
2831+
Datum datum;
2832+
bool isnull;
2833+
2834+
datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
2835+
if (!isnull)
2836+
{
2837+
ArrayType *reloptions = DatumGetArrayTypeP(datum);
2838+
orig = get_value_by_name_from_array(reloptions, ATTOPTION_BBF_ORIGINAL_TABLE_NAME);
2839+
}
2840+
ReleaseSysCache(tuple);
2841+
}
2842+
/* orig remains valid after ReleaseSysCache - get_value_by_name_from_array palloc's a copy */
2843+
return orig;
2844+
}
2845+
28012846
Datum
28022847
object_name(PG_FUNCTION_ARGS)
28032848
{
@@ -2844,7 +2889,12 @@ object_name(PG_FUNCTION_ARGS)
28442889
enr = GetENRTempTableWithOid(object_id, false);
28452890
if (enr != NULL && enr->md.enrtype == ENR_TSQL_TEMP)
28462891
{
2847-
PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text(enr->md.name));
2892+
const char *name = enr->md.name;
2893+
char *orig = get_orig_temp_table_name(object_id);
2894+
2895+
if (orig)
2896+
name = orig;
2897+
PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text(name));
28482898
}
28492899

28502900
/* search in pg_class by object_id */
@@ -2855,7 +2905,17 @@ object_name(PG_FUNCTION_ARGS)
28552905
if (pg_class_aclcheck(object_id, user_id, ACL_SELECT) == ACLCHECK_OK)
28562906
{
28572907
Form_pg_class pg_class = (Form_pg_class) GETSTRUCT(tuple);
2858-
result_text = cstring_to_text(NameStr(pg_class->relname)); // make a copy before releasing syscache
2908+
2909+
if (pg_class->relpersistence == RELPERSISTENCE_TEMP &&
2910+
NameStr(pg_class->relname)[0] == '#')
2911+
{
2912+
char *orig = get_orig_temp_table_name(object_id);
2913+
if (orig)
2914+
result_text = cstring_to_text(orig);
2915+
}
2916+
2917+
if (!result_text)
2918+
result_text = cstring_to_text(NameStr(pg_class->relname));
28592919
schema_id = pg_class->relnamespace;
28602920
}
28612921
ReleaseSysCache(tuple);

contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,6 +3557,11 @@ tsql_IndexStmt:
35573557
n->transformed = false;
35583558
n->if_not_exists = false;
35593559

3560+
if (n->idxname)
3561+
n->options = lappend(n->options,
3562+
makeDefElem("name_location",
3563+
(Node *) makeInteger(@7), @7));
3564+
35603565
tsql_index_nulls_order(n->indexParams, n->accessMethod);
35613566
$$ = (Node *)n;
35623567
}

contrib/babelfishpg_tsql/src/backend_parser/scan-tsql-rule.l

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@
153153
<tsql>{tsql_ttname} {
154154
SET_YYLLOC();
155155
yylval->str = pstrdup(yytext);
156+
if (yyleng >= NAMEDATALEN)
157+
truncate_identifier(yylval->str, yyleng, true);
156158
return IDENT;
157159
}
158160

contrib/babelfishpg_tsql/src/hooks.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,20 +2497,18 @@ pltsql_post_transform_table_definition(ParseState *pstate, RangeVar *relation, c
24972497
stmt->objtype = OBJECT_TABLE;
24982498

24992499
/*
2500-
* Only store original_name if there's a difference, and if the difference
2501-
* is only in capitalization
2500+
* Store original_name in reloptions when:
2501+
* 1. There is a case-only difference between relname and original_name, OR
2502+
* 2. The identifier is a temp table name that was truncated (>= NAMEDATALEN)
25022503
*/
2503-
if (strncmp(relname, original_name, strlen(relname)) != 0 && strncasecmp(relname, original_name, strlen(relname)) == 0)
2504+
if ((strncmp(relname, original_name, strlen(relname)) != 0 && strncasecmp(relname, original_name, strlen(relname)) == 0) ||
2505+
(relation->relpersistence == RELPERSISTENCE_TEMP && original_name[0] == '#' && strlen(original_name) >= NAMEDATALEN))
25042506
{
25052507
/*
25062508
* add "ALTER TABLE SET (bbf_original_table_name=<original_name>)" to
25072509
* alist so that original_name will be stored in pg_class.reloptions
25082510
*/
2509-
cmd_orig_name = makeNode(AlterTableCmd);
2510-
cmd_orig_name->subtype = AT_SetRelOptions;
2511-
cmd_orig_name->def = (Node *) list_make1(makeDefElem(pstrdup(ATTOPTION_BBF_ORIGINAL_TABLE_NAME), (Node *) makeString(pstrdup(original_name)), -1));
2512-
cmd_orig_name->behavior = DROP_RESTRICT;
2513-
cmd_orig_name->missing_ok = false;
2511+
cmd_orig_name = make_original_rel_name_cmd(original_name);
25142512
stmt->cmds = lappend(stmt->cmds, cmd_orig_name);
25152513
}
25162514

contrib/babelfishpg_tsql/src/pl_handler.c

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ extern PLtsql_function *find_cached_batch(int handle);
175175
extern void apply_post_compile_actions(PLtsql_function *func, InlineCodeBlockArgs *args);
176176
Datum sp_prepare(PG_FUNCTION_ARGS);
177177
Datum sp_unprepare(PG_FUNCTION_ARGS);
178-
static List *transformSelectIntoStmt(CreateTableAsStmt *stmt);
178+
static List *transformSelectIntoStmt(CreateTableAsStmt *stmt, const char *queryString);
179179
static char *get_oid_type_string(int type_oid);
180180
static int64 get_identity_into_args(Node *node);
181181
extern char *construct_unique_index_name(char *index_name, char *relation_name);
@@ -239,6 +239,7 @@ static TargetEntry* buildJsonEntry(int nestLevel, char* tableAlias, TargetEntry*
239239
static char *string_to_fixed_hash(const char *input);
240240
static void processAutoColumns(Query *wrapperQuery, Query *origQuery, Alias *wrapperRteAlias, ForAutoContext *ctx, ForAutoMode mode);
241241
extern const char *ATTOPTION_BBF_ORIGINAL_NAME;
242+
extern const char *ATTOPTION_BBF_ORIGINAL_TABLE_NAME;
242243
extern bool pltsql_ansi_defaults;
243244
extern bool pltsql_quoted_identifier;
244245
extern bool pltsql_concat_null_yields_null;
@@ -5386,6 +5387,34 @@ bbf_ProcessUtility(PlannedStmt *pstmt,
53865387
List *partition_schemes = stmt->excludeOpNames;
53875388

53885389
stmt->excludeOpNames = NIL;
5390+
5391+
/*
5392+
* For indexes on temp tables, extract the full original
5393+
* name from the query string using name_location stored
5394+
* by the parser. Remove name_location from options as
5395+
* it is for internal use only.
5396+
*/
5397+
{
5398+
ListCell *lc;
5399+
foreach(lc, stmt->options)
5400+
{
5401+
DefElem *opt = (DefElem *) lfirst(lc);
5402+
if (strcmp(opt->defname, "name_location") == 0)
5403+
{
5404+
if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP &&
5405+
stmt->relation->relname[0] == '#' && original_name)
5406+
{
5407+
int loc = intVal(opt->arg);
5408+
char *full_name = extract_identifier(queryString + loc, NULL);
5409+
if (full_name)
5410+
original_name = full_name;
5411+
}
5412+
stmt->options = foreach_delete_current(stmt->options, lc);
5413+
break;
5414+
}
5415+
}
5416+
}
5417+
53895418
if (stmt->idxname && !stmt->isconstraint)
53905419
stmt->idxname = construct_unique_index_name(stmt->idxname, stmt->relation->relname);
53915420
/*
@@ -7998,7 +8027,8 @@ get_identity_into_args(Node *node)
79988027
}
79998028

80008029
static List *
8001-
transformSelectIntoStmt(CreateTableAsStmt *stmt)
8030+
transformSelectIntoStmt
8031+
(CreateTableAsStmt *stmt, const char *queryString)
80028032
{
80038033
List *result;
80048034
ListCell *elements;
@@ -8239,6 +8269,31 @@ transformSelectIntoStmt(CreateTableAsStmt *stmt)
82398269
}
82408270

82418271
result = lappend(result, stmt);
8272+
8273+
/* Store original name in reloption for SELECT INTO #temp with long names */
8274+
if (into && into->rel &&
8275+
into->rel->relpersistence == RELPERSISTENCE_TEMP &&
8276+
into->rel->relname[0] == '#' &&
8277+
into->rel->location >= 0 && queryString != NULL)
8278+
{
8279+
char *original_name = extract_identifier(queryString + into->rel->location, NULL);
8280+
8281+
if (original_name && strlen(original_name) >= NAMEDATALEN)
8282+
{
8283+
if (!altstmt)
8284+
{
8285+
altstmt = makeNode(AlterTableStmt);
8286+
altstmt->relation = into->rel;
8287+
altstmt->objtype = OBJECT_TABLE;
8288+
altstmt->cmds = NIL;
8289+
}
8290+
altstmt->cmds = lappend(altstmt->cmds, make_original_rel_name_cmd(original_name));
8291+
pfree(original_name);
8292+
}
8293+
else if (original_name)
8294+
pfree(original_name);
8295+
}
8296+
82428297
if (altstmt && list_length(altstmt->cmds) > 0)
82438298
result = lappend(result, altstmt);
82448299

@@ -8251,7 +8306,7 @@ void pltsql_bbfSelectIntoUtility(ParseState *pstate, PlannedStmt *pstmt, const c
82518306

82528307
Node *parsetree = pstmt->utilityStmt;
82538308
List *stmts;
8254-
stmts = transformSelectIntoStmt((CreateTableAsStmt *)parsetree);
8309+
stmts = transformSelectIntoStmt((CreateTableAsStmt *)parsetree, queryString);
82558310
while (stmts != NIL)
82568311
{
82578312
Node *stmt = (Node *)linitial(stmts);

contrib/babelfishpg_tsql/src/pltsql.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,6 +2331,7 @@ extern List *get_columns(char *index_stmt);
23312331
extern char *replace_special_chars_fts_impl(char *input_str);
23322332
extern bool is_unique_index(Oid relid, const char *index_name);
23332333
extern void exec_grantschema_subcmds(const char *schema, const char *rolname, bool is_grant, bool with_grant_option, AclMode privilege);
2334+
extern AlterTableCmd *make_original_rel_name_cmd(const char *original_name);
23342335
extern void exec_add_original_index_name(char *idxname, char *schemaname, char *original_name);
23352336
extern int TsqlUTF8LengthInUTF16(const void *vin, int len);
23362337
extern void TsqlCheckUTF16Length_bpchar(const char *s, int32 len, int32 maxlen, int charlen, bool isExplicit);

contrib/babelfishpg_tsql/src/pltsql_utils.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,23 @@ exec_utility_cmd_helper(char *query_str)
18911891
}
18921892

18931893
extern const char *ATTOPTION_BBF_ORIGINAL_TABLE_NAME;
1894+
/*
1895+
* make_original_rel_name_cmd - Create an AlterTableCmd that stores the
1896+
* original untruncated name in bbf_original_rel_name reloption.
1897+
*/
1898+
AlterTableCmd *
1899+
make_original_rel_name_cmd(const char *original_name)
1900+
{
1901+
AlterTableCmd *cmd = makeNode(AlterTableCmd);
1902+
1903+
cmd->subtype = AT_SetRelOptions;
1904+
cmd->def = (Node *) list_make1(makeDefElem(pstrdup(ATTOPTION_BBF_ORIGINAL_TABLE_NAME),
1905+
(Node *) makeString(pstrdup(original_name)), -1));
1906+
cmd->behavior = DROP_RESTRICT;
1907+
cmd->missing_ok = false;
1908+
return cmd;
1909+
}
1910+
18941911
void
18951912
exec_add_original_index_name(char *idxname, char *schemaname, char *original_name)
18961913
{

0 commit comments

Comments
 (0)