<commit_before>/*-----------------------------------------------------------------------------
 *
 * sql_serializer_oracle.c
 *			  
 *		
 *		AUTHOR: lord_pretzel
 *
 *		
 *
 *-----------------------------------------------------------------------------
 */


#include "common.h"
#include "instrumentation/timing_instrumentation.h"
#include "mem_manager/mem_mgr.h"

#include "log/logger.h"

#include "sql_serializer/sql_serializer_oracle.h"
#include "model/node/nodetype.h"
#include "model/query_operator/query_operator.h"
#include "model/query_operator/operator_property.h"
#include "model/list/list.h"
#include "model/set/set.h"



/* data structures */
typedef enum MatchState {
    MATCH_START,
    MATCH_DISTINCT,
    MATCH_FIRST_PROJ,
    MATCH_HAVING,
    MATCH_AGGREGATION,
    MATCH_SECOND_PROJ,
    MATCH_WHERE,
    MATCH_WINDOW,
    MATCH_ORDER,
    MATCH_NEXTBLOCK
} MatchState;

#define OUT_MATCH_STATE(_state) \
    (_state == MATCH_START ? "MATCH_START" : \
     _state == MATCH_DISTINCT ? "MATCH_DISTINCT" : \
     _state == MATCH_FIRST_PROJ ? "MATCH_FIRST_PROJ" : \
     _state == MATCH_HAVING ? "MATCH_HAVING" : \
     _state == MATCH_AGGREGATION ? "MATCH_AGGREGATION" : \
     _state == MATCH_SECOND_PROJ ? "MATCH_SECOND_PROJ" : \
     _state == MATCH_WHERE ? "MATCH_WHERE" : \
     _state == MATCH_WINDOW ? "MATCH_WINDOW" : \
     _state == MATCH_WINDOW ? "MATCH_ORDER" : \
             "MATCH_NEXTBLOCK" \
     )

typedef struct QueryBlockMatch {
    DuplicateRemoval *distinct;
    ProjectionOperator *firstProj;
    SelectionOperator *having;
    AggregationOperator *aggregation;
    ProjectionOperator *secondProj;
    SelectionOperator *where;
    QueryOperator *fromRoot;
    WindowOperator *windowRoot;
    OrderOperator *orderBy;
} QueryBlockMatch;

#define OUT_BLOCK_MATCH(_level,_m,_message) \
    do { \
        _level ## _LOG ("MATCH INFO: %s", _message); \
        _level ## _LOG ("distinct: %s", operatorToOverviewString((Node *) _m->distinct)); \
        _level ## _LOG ("firstProj: %s", operatorToOverviewString((Node *) _m->firstProj)); \
        _level ## _LOG ("having: %s", operatorToOverviewString((Node *) _m->having)); \
        _level ## _LOG ("aggregation: %s", operatorToOverviewString((Node *) _m->aggregation)); \
        _level ## _LOG ("secondProj: %s", operatorToOverviewString((Node *) _m->secondProj)); \
        _level ## _LOG ("where: %s", operatorToOverviewString((Node *) _m->where)); \
        _level ## _LOG ("fromRoot: %s", operatorToOverviewString((Node *) _m->fromRoot)); \
        _level ## _LOG ("windowRoot: %s", operatorToOverviewString((Node *) _m->windowRoot)); \
        _level ## _LOG ("orderBy: %s", operatorToOverviewString((Node *) _m->orderBy)); \
    } while(0)

typedef struct TemporaryViewMap {
    QueryOperator *viewOp; // the key
    char *viewName;
    char *viewDefinition;
    List *attrNames;
    UT_hash_handle hh;
} TemporaryViewMap;

typedef struct UpdateAggAndGroupByAttrState {
    List *aggNames;
    List *groupByNames;
} UpdateAggAndGroupByAttrState;

typedef struct JoinAttrRenameState {
    int rightFromOffsets;
    List *fromAttrs;
} JoinAttrRenameState;

/* macros */
#define OPEN_PARENS(str) appendStringInfoChar(str, '(')
#define CLOSE_PARENS(str) appendStringInfoChar(str, ')')
#define WITH_PARENS(str,operation) \
    do { \
        OPEN_PARENS(str); \
        operation; \
        CLOSE_PARENS(str); \
    } while(0)

#define ORACLE_IDENT_LIMIT 30

/* variables */
static TemporaryViewMap *viewMap;
static int viewNameCounter;

/* method declarations */
static boolean quoteAttributeNamesVisitQO (QueryOperator *op, void *context);
static boolean quoteAttributeNames (Node *node, void *context);


static void  makeDTOracleConformant(QueryOperator *q);
static boolean replaceNonOracleDTsVisitQO (QueryOperator *node, void *context);
static boolean replaceNonOracleDTs (Node *node, void *context);

static List *serializeQueryOperator (QueryOperator *q, StringInfo str, QueryOperator *parent);
static List *serializeQueryBlock (QueryOperator *q, StringInfo str);
static List *serializeSetOperator (QueryOperator *q, StringInfo str);

static void serializeFrom (QueryOperator *q, StringInfo from, List **fromAttrs);
static void serializeFromItem (QueryOperator *fromRoot, QueryOperator *q, StringInfo from,
        int *curFromItem, int *attrOffset, List **fromAttrs);

static void serializeWhere (SelectionOperator *q, StringInfo where, List *fromAttrs);
static boolean updateAttributeNames(Node *node, List *fromAttrs);
static boolean updateAttributeNamesSimple(Node *node, List *attrNames);

static List *serializeProjectionAndAggregation(QueryBlockMatch *m, StringInfo select,
        StringInfo having, StringInfo groupBy, List *fromAttrs, boolean materialize);

static char *exprToSQLWithNamingScheme(Node *expr, int rOffset, List *fromAttrs);
static boolean renameAttrsVisitor(Node *node, JoinAttrRenameState *state);

static char *createAttrName(char *name, int fItem);
//static char *createFromNames(int *attrOffset, int count);

static List *createTempView(QueryOperator *q, StringInfo str, QueryOperator *parent);
static char *createViewName(void);
static boolean shortenAttributeNames(QueryOperator *q, void *context);
static inline char *getShortAttr(char *newName, int id, boolean quoted);
static void fixAttrReferences (QueryOperator *q);


char *
serializeOperatorModelOracle(Node *q)
{
    StringInfo str = makeStringInfo();
    char *result = NULL;

    // quote ident names if necessary
    ASSERT(IS_OP(q));
    visitQOGraph((QueryOperator *) q, TRAVERSAL_PRE, quoteAttributeNamesVisitQO, NULL);

    // shorten attribute names to confrom with Oracle limits
    if (IS_OP(q))
    {
        // shorten attribute names to oracle's 30 char limit
        visitQOGraph((QueryOperator *) q, TRAVERSAL_PRE,shortenAttributeNames, NULL);
        appendStringInfoString(str, serializeQueryOracle((QueryOperator *) q));
        appendStringInfoChar(str,';');
    }<commit_msg>-ASSERT bug in sql serializer fixed<commit_after>/*-----------------------------------------------------------------------------
 *
 * sql_serializer_oracle.c
 *			  
 *		
 *		AUTHOR: lord_pretzel
 *
 *		
 *
 *-----------------------------------------------------------------------------
 */


#include "common.h"
#include "instrumentation/timing_instrumentation.h"
#include "mem_manager/mem_mgr.h"

#include "log/logger.h"

#include "sql_serializer/sql_serializer_oracle.h"
#include "model/node/nodetype.h"
#include "model/query_operator/query_operator.h"
#include "model/query_operator/operator_property.h"
#include "model/list/list.h"
#include "model/set/set.h"



/* data structures */
typedef enum MatchState {
    MATCH_START,
    MATCH_DISTINCT,
    MATCH_FIRST_PROJ,
    MATCH_HAVING,
    MATCH_AGGREGATION,
    MATCH_SECOND_PROJ,
    MATCH_WHERE,
    MATCH_WINDOW,
    MATCH_ORDER,
    MATCH_NEXTBLOCK
} MatchState;

#define OUT_MATCH_STATE(_state) \
    (_state == MATCH_START ? "MATCH_START" : \
     _state == MATCH_DISTINCT ? "MATCH_DISTINCT" : \
     _state == MATCH_FIRST_PROJ ? "MATCH_FIRST_PROJ" : \
     _state == MATCH_HAVING ? "MATCH_HAVING" : \
     _state == MATCH_AGGREGATION ? "MATCH_AGGREGATION" : \
     _state == MATCH_SECOND_PROJ ? "MATCH_SECOND_PROJ" : \
     _state == MATCH_WHERE ? "MATCH_WHERE" : \
     _state == MATCH_WINDOW ? "MATCH_WINDOW" : \
     _state == MATCH_WINDOW ? "MATCH_ORDER" : \
             "MATCH_NEXTBLOCK" \
     )

typedef struct QueryBlockMatch {
    DuplicateRemoval *distinct;
    ProjectionOperator *firstProj;
    SelectionOperator *having;
    AggregationOperator *aggregation;
    ProjectionOperator *secondProj;
    SelectionOperator *where;
    QueryOperator *fromRoot;
    WindowOperator *windowRoot;
    OrderOperator *orderBy;
} QueryBlockMatch;

#define OUT_BLOCK_MATCH(_level,_m,_message) \
    do { \
        _level ## _LOG ("MATCH INFO: %s", _message); \
        _level ## _LOG ("distinct: %s", operatorToOverviewString((Node *) _m->distinct)); \
        _level ## _LOG ("firstProj: %s", operatorToOverviewString((Node *) _m->firstProj)); \
        _level ## _LOG ("having: %s", operatorToOverviewString((Node *) _m->having)); \
        _level ## _LOG ("aggregation: %s", operatorToOverviewString((Node *) _m->aggregation)); \
        _level ## _LOG ("secondProj: %s", operatorToOverviewString((Node *) _m->secondProj)); \
        _level ## _LOG ("where: %s", operatorToOverviewString((Node *) _m->where)); \
        _level ## _LOG ("fromRoot: %s", operatorToOverviewString((Node *) _m->fromRoot)); \
        _level ## _LOG ("windowRoot: %s", operatorToOverviewString((Node *) _m->windowRoot)); \
        _level ## _LOG ("orderBy: %s", operatorToOverviewString((Node *) _m->orderBy)); \
    } while(0)

typedef struct TemporaryViewMap {
    QueryOperator *viewOp; // the key
    char *viewName;
    char *viewDefinition;
    List *attrNames;
    UT_hash_handle hh;
} TemporaryViewMap;

typedef struct UpdateAggAndGroupByAttrState {
    List *aggNames;
    List *groupByNames;
} UpdateAggAndGroupByAttrState;

typedef struct JoinAttrRenameState {
    int rightFromOffsets;
    List *fromAttrs;
} JoinAttrRenameState;

/* macros */
#define OPEN_PARENS(str) appendStringInfoChar(str, '(')
#define CLOSE_PARENS(str) appendStringInfoChar(str, ')')
#define WITH_PARENS(str,operation) \
    do { \
        OPEN_PARENS(str); \
        operation; \
        CLOSE_PARENS(str); \
    } while(0)

#define ORACLE_IDENT_LIMIT 30

/* variables */
static TemporaryViewMap *viewMap;
static int viewNameCounter;

/* method declarations */
static boolean quoteAttributeNamesVisitQO (QueryOperator *op, void *context);
static boolean quoteAttributeNames (Node *node, void *context);


static void  makeDTOracleConformant(QueryOperator *q);
static boolean replaceNonOracleDTsVisitQO (QueryOperator *node, void *context);
static boolean replaceNonOracleDTs (Node *node, void *context);

static List *serializeQueryOperator (QueryOperator *q, StringInfo str, QueryOperator *parent);
static List *serializeQueryBlock (QueryOperator *q, StringInfo str);
static List *serializeSetOperator (QueryOperator *q, StringInfo str);

static void serializeFrom (QueryOperator *q, StringInfo from, List **fromAttrs);
static void serializeFromItem (QueryOperator *fromRoot, QueryOperator *q, StringInfo from,
        int *curFromItem, int *attrOffset, List **fromAttrs);

static void serializeWhere (SelectionOperator *q, StringInfo where, List *fromAttrs);
static boolean updateAttributeNames(Node *node, List *fromAttrs);
static boolean updateAttributeNamesSimple(Node *node, List *attrNames);

static List *serializeProjectionAndAggregation(QueryBlockMatch *m, StringInfo select,
        StringInfo having, StringInfo groupBy, List *fromAttrs, boolean materialize);

static char *exprToSQLWithNamingScheme(Node *expr, int rOffset, List *fromAttrs);
static boolean renameAttrsVisitor(Node *node, JoinAttrRenameState *state);

static char *createAttrName(char *name, int fItem);
//static char *createFromNames(int *attrOffset, int count);

static List *createTempView(QueryOperator *q, StringInfo str, QueryOperator *parent);
static char *createViewName(void);
static boolean shortenAttributeNames(QueryOperator *q, void *context);
static inline char *getShortAttr(char *newName, int id, boolean quoted);
static void fixAttrReferences (QueryOperator *q);


char *
serializeOperatorModelOracle(Node *q)
{
    StringInfo str = makeStringInfo();
    char *result = NULL;

    // quote ident names if necessary
    ASSERT(IS_OP(q) || isA(q,List));
    if (isA(q,List))
    {
        FOREACH(QueryOperator,el, (List *) q)
            visitQOGraph((QueryOperator *) el, TRAVERSAL_PRE, quoteAttributeNamesVisitQO, NULL);
    }
    else
        visitQOGraph((QueryOperator *) q, TRAVERSAL_PRE, quoteAttributeNamesVisitQO, NULL);

    // shorten attribute names to confrom with Oracle limits
    if (IS_OP(q))
    {
        // shorten attribute names to oracle's 30 char limit
        visitQOGraph((QueryOperator *) q, TRAVERSAL_PRE,shortenAttributeNames, NULL);
        appendStringInfoString(str, serializeQueryOracle((QueryOperator *) q));
        appendStringInfoChar(str,';');
    }
{'fraction_non_alphanumeric': 0.13698967043777668, 'fraction_numerical': 0.000983767830791933, 'mean_word_length': 3.8835068054443553, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4218220', 'n_tokens_mistral': 3882, 'n_tokens_neox': 3685, 'n_words': 879}