static void delete_subtree(Node *pt_to_node) { if (!pt_to_node) return; delete_subtree(pt_to_node->pt_to_left_node); delete_subtree(pt_to_node->pt_to_right_node); free(pt_to_node); }
//------------------------------------------------------------------------------ bool JoinVerb::preprocessQuery( tnode* pStart, tnode* pNode, tnode* pStartOriginal ) { assert( pNode && pStart ); tnode* pJoin = pNode; while( pJoin->left && pJoin->tag != K_JOIN ) pJoin = pJoin->left; assert( pJoin->tag == K_JOIN ); if( pJoin->next && pJoin->next->tag == K_ON ) { addInnerOuterNodes( pJoin->next->left, this->leftTag(), this->rightTag() ); addConditionsToWhere( pJoin->next->left, pStart ); } assert( pJoin->left && (pJoin->left->tag == K_IDENT || pJoin->left->tag == K_AS && pJoin->left->left && pJoin->left->left->tag == K_IDENT ) ); assert( pJoin->right && (pJoin->right->tag == K_IDENT || pJoin->right->tag == K_AS && pJoin->right->left && pJoin->right->left->tag == K_IDENT ) ); tnode* table1 = pJoin->left; pJoin->left = NULL; tnode* table2 = pJoin->right; pJoin->right = NULL; delete_subtree( pNode->left ); delete_subtree( pNode->right ); pNode->tag = K_COMMA; pNode->left = table1; pNode->right = table2; return false; }
/*-------------------------------------------------------------- Routine : record_edit Purpose : record edit in undo buffer ---------------------------------------------------------------*/ void record_edit( TREE *tree, /* tree */ EDIT_TYPE type, /* type of last edit operation */ ITEM *item, /* item associated with edit */ ITEM *subtree, /* sub-tree associated with edit */ ITEM *sibling ) /* sibling of item */ { if ( undo_buf.subtree != NULL ) { delete_subtree( undo_buf.subtree ); } undo_buf.tree = tree; undo_buf.type = type; undo_buf.item = item; undo_buf.subtree = copy_subtree( subtree ); undo_buf.sibling = sibling; }
/*-------------------------------------------------------------- Routine : undo Purpose : undo last edit operation switch ( last operation ) CUT : insert COPY buffer in tree put UNDO buffer back in COPY buffer set last edit to UNDO_CUT UNDO_CUT : record COPY buffer in UNDO buffer record item in COPY buffer delete item set last edit to CUT DELETE : insert UNDO buffer in tree set last edit to ADD ADD : delete the added subtree ( put in UNDO buffer ) set last edit to DELETE CHANGE : record fields of item in tmp copy to item from undo buffer item copy from tmp to undo buffer set last edit to CHANGE SHIFTR : do a shift left set last edit to SHIFTL SHIFTL : do a shift right set last edit to SHIFTR COPY : copy from UNDO buffer to COPY buffer set last edit to UNDO_COPY UNDO_COPY : copy item to COPY buffer ---------------------------------------------------------------*/ void undo() { ITEM *item; ITEM *copy; switch ( undo_buf.type ) { case CUT: /* undo the CUT */ /* copy COPY buffer back into tree */ insert_child( undo_buf.tree, undo_buf.item, copy = get_paste_item( undo_buf.tree ), undo_buf.sibling ); /* copy UNDO buffer into COPY buffer */ copy_to_buffer( undo_buf.tree, undo_buf.subtree ); /* record this edit */ record_edit( undo_buf.tree, UNDO_CUT, copy, NULL, NULL ); break; case UNDO_CUT: /* undo the UNDO_CUT */ item = undo_buf.item; /* record this edit */ record_edit( undo_buf.tree, CUT, undo_buf.item->parent, copy = get_paste_item( undo_buf.tree ), undo_buf.item->right_sib ); /* free unnecessary copy */ delete_subtree( copy ); /* copy item back into COPY buffer */ copy_to_buffer( undo_buf.tree, item ); /* delete item */ delete_child( undo_buf.tree, item ); break; case DELETE: /* put UNDO buffer back in tree */ insert_child( undo_buf.tree, undo_buf.item, copy = copy_subtree( undo_buf.subtree ), undo_buf.sibling ); /* record this edit */ record_edit( undo_buf.tree, ADD, copy, NULL, NULL ); break; case ADD: item = undo_buf.item; /* record this edit */ record_edit( undo_buf.tree, DELETE, undo_buf.item->parent, undo_buf.item, undo_buf.item->right_sib ); /* delete the item */ delete_child( undo_buf.tree, item ); break; case CHANGE: /* not implemented yet */ break; case SHIFTR: shift_item_left( undo_buf.tree, undo_buf.item ); record_edit( undo_buf.tree, SHIFTL, undo_buf.item, NULL, NULL ); break; case SHIFTL: shift_item_right( undo_buf.tree, undo_buf.item ); record_edit( undo_buf.tree, SHIFTR, undo_buf.item, NULL, NULL ); break; case COPY: /* copy from UNDO buffer to COPY buffer */ copy_to_buffer( undo_buf.tree, undo_buf.subtree ); /* record this edit */ record_edit( undo_buf.tree, UNDO_COPY, undo_buf.item, NULL, NULL ); break; case UNDO_COPY: /* record this edit */ record_edit( undo_buf.tree, COPY, undo_buf.item, copy = get_paste_item( undo_buf.tree ), /* save copy buffer */ NULL ); /* free unnecessary copy */ delete_subtree( copy ); /* do copy */ copy_to_buffer( undo_buf.tree, undo_buf.item ); break; case NONE: printf( "undo : nothing to undo\n" ); break; default: printf( "*** WARNING: undo: illegal operation type!\n" ); } }
void delete_tree(Node **const pt_to_pt_to_node) { delete_subtree(*pt_to_pt_to_node); *pt_to_pt_to_node = NULL; }
void clear_tree() { delete_subtree(root); }
//------------------------------------------------------------------------------ bool JoinVerb::preprocessQuery( aq::tnode* pStart, aq::tnode* pNode, aq::tnode* pStartOriginal ) { assert( pNode && pStart ); aq::tnode* pJoin = pNode; while( pJoin->left && pJoin->tag != K_JOIN ) pJoin = pJoin->left; assert( pJoin->tag == K_JOIN ); if( pJoin->next && pJoin->next->tag == K_ON ) { addInnerOuter(pJoin, pJoin->left, this->leftTag()); addInnerOuter(pJoin, pJoin->right, this->rightTag()); // std::vector<std::string> tables; // std::vector<aq::tnode*> tablesNodes; // // if (pJoin->left->tag == K_IDENT) // { // tables.push_back(pJoin->left->getData().val_str); // } // else // { // joinlistToNodeArray(pJoin->left, tablesNodes); // for (auto& n : tablesNodes) // { // tables.push_back(n->getData().val_str); // } // } // aq::addInnerOuterNodes( pJoin->next->left, this->leftTag(), tables ); // tables.clear(); // tablesNodes.clear(); // if (pJoin->right->tag == K_IDENT) // { // tables.push_back(pJoin->left->getData().val_str); // } // else // { // joinlistToNodeArray(pJoin->right, tablesNodes); // for (auto& n : tablesNodes) // { // tables.push_back(n->getData().val_str); // } // } //aq::addInnerOuterNodes( pJoin->next->left, this->rightTag(), tables ); aq::addConditionsToWhere( pJoin->next->left, pStart ); } // FIXME //assert( pJoin->left && (pJoin->left->tag == K_IDENT || pJoin->left->tag == K_AS && pJoin->left->left && pJoin->left->left->tag == K_IDENT ) ); //assert( pJoin->right && (pJoin->right->tag == K_IDENT || pJoin->right->tag == K_AS && pJoin->right->left && pJoin->right->left->tag == K_IDENT ) ); aq::tnode* table1 = pJoin->left; pJoin->left = NULL; aq::tnode* table2 = pJoin->right; pJoin->right = NULL; delete_subtree( pNode->left ); delete_subtree( pNode->right ); pNode->tag = K_COMMA; pNode->left = table1; pNode->right = table2; return false; }